Docs-Builder

# Architecture

Version: 1.1.1
Last Updated: January 23, 2026


Identity & Data Model

  • Canonical identity: website_users table (email unique via idx_website_users_email_lower).
  • Transitional identity: users table (CLI legacy). Bridge by email; auto-create website_users on claim if absent.
  • Sessions: auth_sessions stores refresh token hashes, device_id, expiry.
  • Installations: installations (optional) tracks devices; used for device approval visibility.

User States

  • Unregistered: No account, limited core features.
  • Registered Free: Account + login, core features enabled.
  • Licensed: renpy_free, pro, team, enterprise (and Basic in legacy docs) with entitlements.

Tokens

  • Access Token: JWT, 15 min, memory only, RS256, aud branchpy-api.
  • Refresh Token: Opaque, 30–90 days, stored in auth.json, hashed in DB.
  • License Token (Entitlements JWT): 30–90 days, offline verification via embedded public key, includes plan, features, max_offline_days (default 30).

Core Flows

  • Login: POST /v1/auth/login → access + refresh + license tokens → store refresh/license on disk; access in memory.
  • Refresh: POST /v1/auth/refresh → new access + license tokens; revoke on invalid/expired.
  • Whoami: GET /v1/auth/me → profile, plan, expiry (debug/validation).
  • Entitlements: GET /v1/license/me and GET /v1/license/entitlements → plan, features, expiry, max_offline_days.
  • Claim Ren’Py License: POST /v1/claim/renpy (idempotent) → always 200 with token; sets plan renpy_free.
  • Device Flow: POST /v1/auth/device/start → device_code + user_code; poll /v1/auth/device/poll until approved; then issue tokens; sync to auth.json.
  • Offline Mode: Allowed until max_offline_days and JWT exp respected; prompt refresh when exceeded.

Endpoint Contract (Auth/Licensing)

  • /v1/auth/login (email + password or device approval); returns access/refresh/license tokens.
  • /v1/auth/refresh (refresh token) → access + license tokens.
  • /v1/auth/me → user info (id, email, plan, expiry).
  • /v1/auth/device/start → { device_code, user_code, verification_uri, interval }.
  • /v1/auth/device/poll → exchanges approved device_code for tokens.
  • /v1/license/me → entitlements snapshot.
  • /v1/license/entitlements → entitlements (alias; retained for compatibility).
  • /v1/claim/renpy → issues/refreshes renpy_free license (idempotent).

Identity Bridge (Dual Auth Systems)

  • Preferred: website auth (website_users).
  • Bridge logic (claim endpoint): try website_users by sub → fallback by email → auto-create website_users if missing → proceed with claim.
  • Migration 024 enforces case-insensitive unique email to support bridging.

Governance & Logging

  • Emit auth.login_success|failed, auth.refresh_*, auth.logout, auth.token_revoked, license.entitlement_check, license.claim, installation.device_approved.
  • Schemas: see Technical/events/catalog.md (Auth and License topics). Do not duplicate event field definitions here.

Security Notes

  • RS256 signatures; no PII in license tokens (user_id only).
  • Refresh tokens hashed in DB; store on disk with user-only permissions.
  • Rate limiting recommended on /auth/login, /auth/device/start, /auth/device/poll.
  • Ren’Py claim intentionally low-friction; honor system with optional evidence.

Evolution Notes

  • Legacy endpoints /v1/entitlements, /v1/license/status removed (Auth System Closure).
  • Device approval UX fixes pending (polling diagnostics in extension, see troubleshooting).
  • Future: consolidate to single auth system, add SSO, deprecate users table.

Source References (v1.1.0)

  • licensing/License_Architecture_v1.0_CANONICAL.md
  • licensing/AUTH_FLOW.md
  • licensing/BACKEND_API.md
  • auth-system-closure/SPECIFICATION.md
  • auth-licensing-sso/AUTHENTICATION_FIXES_2026-01-22.md