---
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.