--- since: 1.2.1 --- # DjangoPlay — Authentication Architecture DjangoPlay uses AuthX as its external identity service. DjangoPlay provides the application-facing authentication boundary for web and API clients, while AuthX remains the identity authority responsible for identity operations and JWT issuance. The architecture separates: * Authentication and identity management * JWT issuance and verification * DjangoPlay application user context * Application authorization and RBAC AuthX is the **sole JWT signing authority** for the DjangoPlay identity architecture. DjangoPlay verifies AuthX-issued JWTs but does not sign them. ## Architecture ```mermaid flowchart TD WEB["Web Browser
DjangoPlay UI"] API["REST API Client
DjangoPlay APIs"] SSO["SSO Provider
Google / Other configured provider"] AUTH_BOUNDARY["DjangoPlay Authentication Boundary
Login / Signup / Password Reset / SSO"] AUTHX["AuthX Identity Service
Identity Authority"] USERS["AuthX Identity Data
Users / Credentials / Identity State"] DB["AuthX PostgreSQL
Identity Store"] JWT["AuthX-issued JWT
Signed by AuthX"] VERIFY["DjangoPlay JWT Verification
Signature / Issuer / Audience / Claims"] CONTEXT["DjangoPlay Application User Context
Authenticated User / Identity Context"] AUTHZ["DjangoPlay Authorization
Permissions / RBAC / Policies"] APP["DjangoPlay Application
Web Views / DRF APIs / Services"] WEB --> AUTH_BOUNDARY API --> AUTH_BOUNDARY SSO --> AUTH_BOUNDARY AUTH_BOUNDARY --> AUTHX AUTHX --> USERS USERS --> DB AUTHX --> JWT JWT --> VERIFY VERIFY --> CONTEXT CONTEXT --> AUTHZ AUTHZ --> APP classDef client fill:#e6f1fb,stroke:#2474b5,stroke-width:2px,color:#174d7a classDef boundary fill:#e5f6f1,stroke:#159a7a,stroke-width:2px,color:#075d4b classDef identity fill:#fff2d9,stroke:#d89b18,stroke-width:2px,color:#76520b classDef token fill:#eeeaff,stroke:#7655c7,stroke-width:2px,color:#4a3485 classDef application fill:#f5f3ed,stroke:#777777,stroke-width:1px,color:#444444 classDef data fill:#eeeeff,stroke:#5a55c9,stroke-width:2px,color:#403b91 class WEB,API,SSO client class AUTH_BOUNDARY boundary class AUTHX identity class USERS,DB data class JWT,VERIFY token class CONTEXT,AUTHZ,APP application ```` ## Authentication Flow ```text CLIENTS ┌────────┼─────────┐ │ │ │ ▼ ▼ ▼ Web REST SSO Browser Client Provider │ │ │ └────────┼─────────┘ ▼ DjangoPlay Authentication Boundary │ ▼ AuthX Identity Service │ ┌────────────┼────────────┐ ▼ ▼ ▼ Users Credentials Identity State │ ▼ AuthX PostgreSQL │ │ AuthX signs JWT │ ▼ JWT │ ▼ DjangoPlay verifies │ ▼ Application User Context │ ▼ Permissions / RBAC / Policy │ ▼ DjangoPlay Application ``` ## Authentication Responsibilities | Component | Responsibility | | ---------------------------------- | ----------------------------------------------------------------------------------------------------- | | Web Browser | Initiates browser-based authentication and consumes the authenticated DjangoPlay application | | REST API Client | Initiates API authentication and presents the resulting authentication credential to DjangoPlay APIs | | SSO Provider | Provides external identity information for configured SSO flows such as Google | | DjangoPlay Authentication Boundary | Provides the application-facing authentication entry points and coordinates authentication with AuthX | | AuthX Identity Service | Owns identity operations, credentials, identity state, and JWT issuance | | AuthX PostgreSQL | Persists AuthX identity data | | JWT | Carries the authenticated identity and claims issued by AuthX | | DjangoPlay JWT Verification | Validates AuthX-issued JWTs before establishing authenticated application context | | Application User Context | Makes authenticated identity available to DjangoPlay application processing | | Authorization / RBAC | Determines what the authenticated identity is allowed to do | | DjangoPlay Application | Executes the authorized web/API request and business workflow | ## Identity Authority AuthX is the identity authority for DjangoPlay. Authentication operations such as: * Login * Signup * Password reset * SSO * Identity management are integrated through the AuthX identity service. DjangoPlay provides the application-facing authentication boundary but does not become the authoritative identity store. ```text DjangoPlay │ │ identity operations ▼ AuthX │ ├── Users ├── Credentials ├── Identity state └── JWT issuance ``` AuthX therefore remains the source of truth for identity. ## JWT Authority AuthX is the **sole JWT signing authority**. ```text AuthX │ │ signs ▼ JWT │ │ presented to ▼ DjangoPlay │ │ verifies ▼ Authenticated Application Context ``` DjangoPlay does **not** sign AuthX identity JWTs. The AuthX private signing key remains with AuthX and must not be exposed to DjangoPlay browser clients or other consumers. DjangoPlay uses the corresponding public key to verify AuthX-issued tokens. ## JWT Verification Boundary DjangoPlay treats JWT verification as an authentication boundary. The verification process establishes whether an incoming token can be trusted as an AuthX-issued identity credential. Conceptually: ```text Incoming JWT │ ▼ Signature verification │ ▼ Issuer validation │ ▼ Audience validation │ ▼ Claims / identity extraction │ ▼ Authenticated user context ``` The exact verification implementation belongs to DjangoPlay's authentication and middleware/security layers. Authentication establishes **who the caller is**. Authorization is a separate application concern. ## Authentication vs Authorization DjangoPlay deliberately separates authentication from authorization. ```text Authentication │ │ Who is this user? ▼ Authenticated Identity │ ▼ Authorization │ │ What may this user do? ▼ Permissions / RBAC / Policies │ ▼ Application Operation ``` AuthX establishes identity. DjangoPlay applies application-level authorization. For example, a valid AuthX identity does not automatically grant access to every DjangoPlay resource or operation. The application may apply: * Roles * Permissions * Object-level access rules * RBAC * Application policies after authentication has been established. ## Web Authentication The browser-facing authentication flow is handled through DjangoPlay's authentication boundary. Conceptually: ```text Browser │ ▼ DjangoPlay Login / Authentication │ ▼ AuthX │ ├── Authenticate identity ├── Perform identity operation └── Issue authentication credential │ ▼ DjangoPlay │ ├── Verify authentication state ├── Establish application context └── Apply authorization │ ▼ DjangoPlay Web Application ``` The browser should never receive or manage the AuthX private signing key. ## REST API Authentication API clients follow the same identity-authority model. ```text REST Client │ ▼ DjangoPlay API │ ▼ Authentication / Token Verification │ ▼ AuthX-issued JWT │ ▼ Verified Identity │ ▼ Permissions / RBAC │ ▼ API View / ViewSet │ ▼ Application Services ``` The API layer therefore does not independently become a second identity authority. ## SSO Authentication Configured SSO providers such as Google participate in the authentication flow as external identity providers. ```text Browser │ ▼ DjangoPlay SSO Entry │ ▼ Configured SSO Provider │ ▼ External Identity │ ▼ DjangoPlay / AuthX Identity Flow │ ▼ Authenticated DjangoPlay Identity ``` SSO provider credentials are configuration-dependent and are not required when SSO is not enabled or being tested. ## Credential Boundaries DjangoPlay and AuthX intentionally maintain separate credential boundaries. | Credential / Key | Owner | Purpose | | ---------------------------- | ------------------------------- | ----------------------------------------------- | | `DB_PASSWORD` | DjangoPlay | DjangoPlay PostgreSQL authentication | | `POSTGRES_PASSWORD` | AuthX | AuthX PostgreSQL authentication | | `DATABASE_URL` in `.secrets` | DjangoPlay | DjangoPlay database connection | | `DATABASE_URL` in `.authx` | AuthX | AuthX asynchronous database connection | | `DATABASE_URL_SYNC` | AuthX | AuthX synchronous database/migration connection | | `JWT_SIGNING_KEY` | DjangoPlay | DjangoPlay's own JWT-related functionality | | `JWT_PRIVATE_KEY` | AuthX | AuthX identity JWT signing | | `JWT_PUBLIC_KEY` | AuthX / DjangoPlay verification | Verification of AuthX-issued JWTs | | `AUTHX_SERVICE_TOKEN` | DjangoPlay ↔ AuthX | Backend service authentication | | `JWT_ISSUER` | AuthX | Identity authority asserted in the JWT | | `JWT_AUDIENCE` | AuthX / consuming application | Intended JWT audience | Do not mix these credentials. In particular: ```text DB_PASSWORD != POSTGRES_PASSWORD JWT_SIGNING_KEY != JWT_PRIVATE_KEY AUTHX_SERVICE_TOKEN != POSTGRES_PASSWORD ``` DjangoPlay must not use the AuthX private signing key as its own application secret or signing credential. ## AuthX Service URL vs JWT Issuer `APP_BASE_URL` and `JWT_ISSUER` describe different concepts. ```text APP_BASE_URL Where the AuthX service is reachable. JWT_ISSUER The identity authority asserted inside the JWT. ``` For local development, AuthX may be reachable at: ```text APP_BASE_URL=http://127.0.0.1:8100 ``` while the JWT authority may be: ```text JWT_ISSUER=https://auth.djangoplay.org ``` These values therefore do not have to be identical. The service URL describes network communication. The issuer identifies the authority that issued the identity token. ## AuthX Database Boundary AuthX maintains its own PostgreSQL identity store. ```text DjangoPlay PostgreSQL │ └── DjangoPlay application data AuthX PostgreSQL │ └── AuthX identity data ``` The two databases have separate credentials and separate responsibilities. DjangoPlay should not treat its application database as the authoritative store for AuthX credentials or identity state. ## Service-to-Service Authentication DjangoPlay communicates with AuthX using the dedicated service credential: ```text AUTHX_SERVICE_TOKEN ``` Conceptually: ```text DjangoPlay │ │ AUTHX_SERVICE_TOKEN ▼ AuthX ``` This credential is intended for backend service authentication. It must not be exposed to browser clients or embedded into frontend assets. It is also separate from: * PostgreSQL passwords * JWT signing keys * OAuth client secrets * User authentication credentials ## Local vs Production The authentication architecture remains the same across environments, while the concrete service endpoints, credentials, origins, and signing keys may differ. Typical differences include: | Area | Local Development | Production | | ---------------- | ------------------------- | ------------------------------- | | AuthX service | Local AuthX instance | Deployed AuthX service | | `APP_BASE_URL` | Local AuthX URL | Deployment-specific AuthX URL | | `JWT_ISSUER` | Environment-specific | Production AuthX authority | | JWT keys | Development key pair | Dedicated production key pair | | CORS origins | Local development origins | Production application origins | | Service token | Development credential | Dedicated production credential | | Google SSO | Only when being tested | Only when enabled | | AuthX PostgreSQL | Local AuthX database | Dedicated AuthX database | Production credentials and signing keys must never be reused casually from development environments. ## Security Principles The authentication architecture follows these boundaries: 1. **AuthX owns identity.** 2. **AuthX is the sole JWT signing authority.** 3. **DjangoPlay verifies AuthX-issued JWTs.** 4. **DjangoPlay does not sign AuthX identity JWTs.** 5. **AuthX private signing keys remain exclusively with AuthX.** 6. **DjangoPlay authorization is separate from authentication.** 7. **Application roles and permissions are enforced by DjangoPlay.** 8. **DjangoPlay and AuthX use separate database credentials.** 9. **Backend service credentials are never exposed to browser clients.** 10. **SSO providers participate in authentication but do not replace AuthX as DjangoPlay's identity authority.** ## Architectural Principle DjangoPlay deliberately separates identity from application behavior. ```text IDENTITY │ ▼ AuthX │ │ JWT ▼ DjangoPlay │ ▼ Authorization │ ▼ Application Logic ``` This separation allows DjangoPlay to keep authentication and identity responsibilities centralized while retaining ownership of application-specific authorization, permissions, roles, and business workflows.