--- since: 1.1.1 --- # AuthX — Architecture **Version:** 1.0.0 **Date:** 2026-08-29 --- ## 1. Overview AuthX is a standalone identity service designed to provide centralized authentication and identity management for applications that need a dedicated identity authority. AuthX is implemented as a **FastAPI microservice** with its own PostgreSQL persistence layer and exposes two principal API surfaces: 1. A public OIDC-compatible API for authentication, token issuance, token refresh, identity information, discovery, and public-key distribution. 2. An internal identity-management API for trusted backend services. AuthX is the authoritative owner of: - Identity records - Email addresses - Password credentials - Password hashes - SSO identity associations - Identity status - Authentication - Access-token issuance - Refresh-token state - JWT signing keys A consuming application owns its own application/domain data and references an AuthX identity by its stable identity identifier. The consuming application does **not** become the identity authority. --- ## 2. Architectural Role AuthX sits between clients and consuming applications as an independent identity authority. ```mermaid flowchart TD CLIENT["Client
Browser / Mobile / CLI / API Client"] AUTHX["AuthX
Identity Service"] CONSUMER1["Consuming Application A"] CONSUMER2["Consuming Application B"] CONSUMER3["Consuming Application C"] DB["AuthX PostgreSQL"] CLIENT -->|"Authentication / Tokens"| AUTHX AUTHX -->|"JWT"| CLIENT AUTHX --> DB CLIENT -->|"Bearer JWT"| CONSUMER1 CLIENT -->|"Bearer JWT"| CONSUMER2 CLIENT -->|"Bearer JWT"| CONSUMER3 CONSUMER1 -->|"Trusted backend API"| AUTHX CONSUMER2 -->|"Trusted backend API"| AUTHX CONSUMER3 -->|"Trusted backend API"| AUTHX ```` The architecture deliberately separates: ```text Identity Authority │ ▼ AuthX │ ├── Identity ├── Credentials ├── Authentication └── Tokens Application Authority │ ▼ Consuming Application │ ├── Profiles ├── Organizations ├── Roles ├── Permissions └── Domain Data ``` AuthX does not attempt to own application-specific authorization or domain data. --- ## 3. Core Architectural Principles AuthX follows several core principles. | Principle | Description | | ---------------------------- | ----------------------------------------------------------------- | | Dedicated Identity Authority | AuthX owns authentication identity and credentials | | Service Separation | Identity is separated from consuming application logic | | API First | Authentication and identity operations are exposed through APIs | | OIDC Compatible | Public authentication endpoints follow an OIDC-oriented interface | | JWT Based | Access tokens are signed JWTs | | Asymmetric Signing | AuthX signs JWTs using RSA / RS256 | | Stateless Access Tokens | Access-token validation does not require AuthX database access | | Stateful Refresh Tokens | Refresh-token state supports rotation and revocation | | Backend Trust Boundary | Internal identity management requires a service credential | | Database Isolation | AuthX maintains its own identity database | | Consumer Independence | Any suitable application can consume AuthX | | Local Verification | Consumers can verify JWTs using the public key/JWKS | --- ## 4. High-Level Architecture ```mermaid flowchart TB subgraph CLIENTS["Clients"] WEB["Web Browser"] MOBILE["Mobile Client"] CLI["CLI / Other Client"] end subgraph AUTHX["AuthX Identity Service"] API["FastAPI API"] OIDC["OIDC API"] INTERNAL["Internal Identity API"] IDENTITY["Identity Service"] SECURITY["Security / JWT"] MODELS["Identity Models"] REFRESH["Refresh Token State"] end DB[("AuthX PostgreSQL")] subgraph CONSUMERS["Consuming Applications"] APP1["Application A"] APP2["Application B"] APP3["Application C"] end WEB --> OIDC MOBILE --> OIDC CLI --> OIDC OIDC --> SECURITY OIDC --> IDENTITY INTERNAL --> IDENTITY IDENTITY --> MODELS IDENTITY --> REFRESH MODELS --> DB REFRESH --> DB SECURITY -->|"Signed JWT"| WEB SECURITY -->|"Signed JWT"| MOBILE SECURITY -->|"Signed JWT"| CLI WEB -->|"Bearer JWT"| APP1 MOBILE -->|"Bearer JWT"| APP2 CLI -->|"Bearer JWT"| APP3 APP1 -->|"X-Service-Token"| INTERNAL APP2 -->|"X-Service-Token"| INTERNAL APP3 -->|"X-Service-Token"| INTERNAL ``` --- ## 5. AuthX Package Architecture The distribution contains two logical packages: ```text authx-identity │ ├── authx/ │ │ │ ├── FastAPI microservice │ ├── API routes │ ├── configuration │ ├── security │ ├── database │ ├── models │ ├── schemas │ ├── services │ └── middleware │ └── authx_client/ │ ├── AuthXClient └── AuthXJWT ``` The `authx` package is the identity service itself. The `authx_client` package is a consumer-side helper for applications that need to communicate with an AuthX deployment. The current distribution explicitly packages both components. They have different responsibilities and deployment roles. --- ## 6. AuthX Internal Structure The current package is organized into distinct technical areas: ```text authx/ │ ├── __init__.py ├── main.py │ ├── api/ │ ├── deps.py │ └── v1/ │ ├── endpoints/ │ │ └── oidc.py │ │ │ └── internal/ │ └── identities.py │ ├── core/ │ ├── logging.py │ ├── security.py │ └── settings.py │ ├── db/ │ └── session.py │ ├── middleware/ │ └── logging.py │ ├── models/ │ ├── refresh_token.py │ └── user_identity.py │ ├── schemas/ │ └── identity.py │ └── services/ └── identity_service.py ``` This structure separates: * HTTP/API concerns * Security concerns * Configuration * Persistence * Domain models * Request/response schemas * Identity business operations * Middleware The package layout is confirmed by the built AuthX distribution. --- ## 7. Application Entry Point The FastAPI service is exposed through: ```text authx.main:app ``` The application is normally run using Uvicorn. Example: ```bash uvicorn authx.main:app --host 0.0.0.0 --port 8100 ``` In containerized deployments, migrations are applied before the service starts. The default development service endpoint is: ```text http://localhost:8100 ``` --- ## 8. API Architecture AuthX exposes two API boundaries. ```mermaid flowchart TD REQUEST["Incoming Request"] REQUEST --> PUBLIC{"Public API?"} PUBLIC -->|"Yes"| OIDC["OIDC / Public Endpoints"] PUBLIC -->|"No"| INTERNAL["Internal API"] OIDC --> AUTH["Credential / JWT Authentication"] INTERNAL --> SERVICE["X-Service-Token Validation"] AUTH --> SERVICE_LAYER["AuthX Services"] SERVICE --> SERVICE_LAYER SERVICE_LAYER --> DB[("PostgreSQL")] ``` ### Public API Public endpoints are designed for clients and consuming systems. ```text GET /.well-known/openid-configuration GET /jwks POST /token POST /token/refresh GET /userinfo GET /health ``` ### Internal API Internal endpoints manage identity records. ```text POST /internal/identities GET /internal/identities/{id} GET /internal/identities/by-email/{email} GET /internal/identities/by-sso/lookup PATCH /internal/identities/{id} DELETE /internal/identities/{id} ``` Internal endpoints require: ```http X-Service-Token: ``` The public and internal APIs therefore represent different trust boundaries. --- ## 9. OIDC Architecture AuthX provides an OIDC-compatible public surface. ```mermaid flowchart LR CLIENT["Client"] DISCOVERY["/.well-known/
openid-configuration"] TOKEN["/token"] REFRESH["/token/refresh"] USERINFO["/userinfo"] JWKS["/jwks"] AUTHX["AuthX"] CLIENT --> DISCOVERY CLIENT --> TOKEN CLIENT --> REFRESH CLIENT --> USERINFO CLIENT --> JWKS DISCOVERY --> AUTHX TOKEN --> AUTHX REFRESH --> AUTHX USERINFO --> AUTHX JWKS --> AUTHX ``` The discovery endpoint publishes the service metadata required by consumers. The current implementation advertises: ```text response_types_supported: ["token"] subject_types_supported: ["public"] scopes_supported: ["openid", "email", "profile"] grant_types_supported: ["password", "refresh_token"] ``` --- ## 10. Authentication Architecture The authentication flow is centered around the identity stored in AuthX. For password authentication: ```mermaid sequenceDiagram participant C as Client participant A as AuthX participant DB as PostgreSQL C->>A: POST /token
email + password A->>DB: Find identity DB-->>A: Identity + password hash A->>A: Verify password A->>A: Validate identity status A->>A: Create access JWT A->>A: Create refresh JWT A->>DB: Persist refresh-token state A-->>C: Access + Refresh tokens ``` AuthX therefore owns the complete credential verification operation. A consuming application does not need to know the password hash or implement the password verification algorithm itself. --- ## 11. Identity Service The identity service is the main business boundary inside AuthX. Its responsibilities include: * Creating identities * Looking up identities * Updating identities * Looking up SSO identities * Handling identity status * Soft deletion * Credential handling * Identity-related validation The API layer delegates identity operations to the service layer rather than embedding persistence logic directly into route handlers. ```text HTTP Request │ ▼ API Endpoint │ ▼ Identity Service │ ├── Validation ├── Identity rules ├── Password handling └── Persistence │ ▼ SQLAlchemy / Database │ ▼ PostgreSQL ``` --- ## 12. Identity Data Model AuthX currently maintains two primary persistence models: ```text UserIdentity │ │ 1 │ │ N ▼ RefreshToken ``` ### UserIdentity Represents the authoritative AuthX identity. Important attributes include: ```text id email username password_hash sso_provider sso_id is_active is_verified is_staff is_superuser created_at updated_at deleted_at last_login ``` The identity is the source of truth for authentication-related identity data. ### RefreshToken Represents server-side refresh-token state. Important attributes include: ```text id identity_id jti is_revoked expires_at created_at ``` The `jti` provides the lookup identity for refresh-token state. --- ## 13. Database Architecture AuthX uses PostgreSQL as its persistent identity store. ```mermaid flowchart TB AUTHX["AuthX FastAPI"] SESSION["Database Session"] IDENTITY["UserIdentity"] REFRESH["RefreshToken"] PG[("AuthX PostgreSQL")] AUTHX --> SESSION SESSION --> IDENTITY SESSION --> REFRESH IDENTITY --> PG REFRESH --> PG ``` The database is an AuthX-owned persistence boundary. A consuming application should not directly connect to the AuthX database for identity operations. Instead: ```text Consumer │ ▼ AuthX API │ ▼ AuthX Database ``` This preserves AuthX as the identity authority. --- ## 14. Password Security Passwords are never stored as plaintext. The persisted credential is: ```text password_hash ``` Password hashing is handled inside AuthX. Conceptually: ```text Plain Password │ ▼ Password Hashing │ ▼ password_hash │ ▼ PostgreSQL ``` Authentication performs verification against the stored hash. The hash is never returned through the internal or public identity responses. --- ## 15. JWT Architecture AuthX is the **sole JWT signing authority**. ```mermaid flowchart LR AUTHX["AuthX"] PRIVATE["RSA Private Key"] JWT["Signed JWT
RS256"] CONSUMER["Consumer"] PUBLIC["RSA Public Key
or JWKS"] VERIFY["Local JWT Verification"] AUTHX --> PRIVATE PRIVATE --> JWT JWT --> CONSUMER CONSUMER --> PUBLIC PUBLIC --> VERIFY JWT --> VERIFY ``` AuthX signs tokens using: ```text RS256 ``` The private signing key remains inside the AuthX deployment. Consumers receive only the public key. --- ## 16. JWT Issuer and Audience AuthX requires explicit JWT issuer and audience configuration. ```text JWT_ISSUER JWT_AUDIENCE ``` `JWT_ISSUER` identifies the identity authority. It must be a valid HTTP(S) URL without a query string or fragment. Production deployments require HTTPS. `JWT_AUDIENCE` identifies the intended application or API consuming the token. These values are validated both when AuthX issues tokens and when consumers verify them. This creates an explicit trust relationship: ```text AuthX │ ├── iss = configured JWT_ISSUER │ └── aud = configured JWT_AUDIENCE │ ▼ Consumer validates expected issuer/audience ``` The issuer is an identity authority identifier; it does not necessarily have to be the same URL that a backend uses to reach the AuthX process. --- ## 17. JWT Claims Access tokens currently contain identity and token metadata such as: ```text sub iss aud iat exp jti type = access email username is_verified is_staff is_superuser ``` Refresh tokens contain: ```text sub iss aud iat exp jti type = refresh ``` The `type` claim allows consumers and AuthX to distinguish access tokens from refresh tokens. --- ## 18. JWKS Architecture AuthX exposes: ```http GET /jwks ``` The endpoint returns the public signing key as a JSON Web Key Set. A consumer can therefore verify a JWT without obtaining the private signing key. ```mermaid sequenceDiagram participant C as Consumer participant J as AuthX /jwks participant A as AuthX C->>J: GET /jwks J-->>C: Public JWK Set A->>A: Sign JWT with private key A-->>C: JWT C->>C: Verify JWT using public key ``` Current key metadata includes: ```text kty = RSA use = sig alg = RS256 kid = authx-key-1 ``` Consumers may cache the JWKS according to their own verification strategy. --- ## 19. Access Token Architecture Access tokens are designed for stateless authentication. The important distinction is: ```text Access Token │ ├── Signed by AuthX ├── Contains claims ├── Has expiration └── Can be locally verified ``` A consumer does not need to make an AuthX HTTP request for every authenticated API request merely to verify the JWT signature. Instead: ```text Client │ │ Authorization: Bearer JWT ▼ Consumer API │ ▼ Local JWT verification │ ├── Signature ├── Algorithm ├── Issuer ├── Audience └── Expiration ``` This is a major scalability property of the architecture. --- ## 20. Refresh Token Architecture Refresh tokens intentionally use server-side state. ```mermaid flowchart TD CLIENT["Client"] REFRESH["Refresh Token"] AUTHX["AuthX"] JWT["JWT Validation"] STATE["RefreshToken Database State"] NEW["New Access + Refresh Token"] CLIENT --> REFRESH REFRESH --> AUTHX AUTHX --> JWT JWT --> STATE STATE -->|"Valid / not revoked"| NEW STATE -->|"Revoked / expired"| REJECT["Reject"] NEW --> CLIENT ``` AuthX supports refresh-token rotation. The high-level behavior is: 1. Receive refresh token. 2. Validate its JWT. 3. Identify the refresh-token `jti`. 4. Check server-side state. 5. Reject revoked or expired state. 6. Mark the presented refresh token revoked. 7. Issue a new access token. 8. Issue a replacement refresh token. This provides revocation and rotation capabilities that a purely stateless refresh-token implementation would not provide. --- ## 21. Userinfo Architecture The public identity endpoint is: ```http GET /userinfo Authorization: Bearer ``` The endpoint validates the access token and returns the public identity representation. Example: ```json { "sub": "", "email": "user@example.com", "email_verified": true, "preferred_username": "user" } ``` The public response intentionally contains significantly less information than the internal identity representation. --- ## 22. Internal Identity API Architecture The internal API exists for trusted backend consumers. ```mermaid sequenceDiagram participant APP as Consumer Backend participant AUTH as AuthX participant DB as PostgreSQL APP->>AUTH: X-Service-Token AUTH->>AUTH: Validate service credential APP->>AUTH: Identity operation AUTH->>AUTH: Identity Service AUTH->>DB: Read / Write identity DB-->>AUTH: Result AUTH-->>APP: Identity response ``` Supported operations include: ```text POST /internal/identities GET /internal/identities/{id} GET /internal/identities/by-email/{email} GET /internal/identities/by-sso/lookup PATCH /internal/identities/{id} DELETE /internal/identities/{id} ``` The internal API is not intended to replace the public authentication API. It exists to allow trusted services to provision and manage identities. --- ## 23. Internal Service Authentication Every internal identity-management request requires: ```http X-Service-Token: ``` AuthX compares the supplied credential against its configured internal service token. The trust relationship is: ```text Trusted Backend │ │ X-Service-Token ▼ AuthX Internal API │ ▼ Identity Service ``` The service credential must remain server-side. It must never be exposed through: * Browser JavaScript * Mobile applications * Public API responses * Client-side configuration * User-visible configuration --- ## 24. Soft Deletion Identity deletion is implemented as a soft-delete operation. The identity is retained, while its active state is disabled and deletion metadata is recorded. Conceptually: ```text DELETE /internal/identities/{id} │ ▼ UserIdentity │ ├── deleted_at = current UTC time └── is_active = false ``` Deleted identities are excluded from normal identity lookup and authentication flows. This preserves historical identity data while preventing normal use of the account. --- ## 25. Consumer Architecture AuthX is intentionally consumer-agnostic. DjangoPlay is only one possible consumer. ```mermaid flowchart TB AUTHX["AuthX
Identity Authority"] DP["Django Application"] MOBILE["Mobile Backend"] API["REST API Platform"] CLI["CLI / Developer Tool"] OTHER["Other Application"] AUTHX -->|"JWT"| DP AUTHX -->|"JWT"| MOBILE AUTHX -->|"JWT"| API AUTHX -->|"JWT"| CLI AUTHX -->|"JWT"| OTHER DP -->|"Internal API"| AUTHX MOBILE -->|"Internal API"| AUTHX API -->|"Internal API"| AUTHX CLI -->|"Internal API"| AUTHX OTHER -->|"Internal API"| AUTHX ``` Each consumer is responsible for its own domain. For example: ```text AuthX └── Identity: 1234 DjangoPlay └── User profile └── Organization membership └── Application permissions Another Application └── Customer profile └── Application-specific roles ``` The AuthX identity identifier provides the connection between these systems. --- ## 26. Consumer-Side Integration Library The distribution provides: ```text authx_client ``` with two important abstractions: ```text AuthXClient AuthXJWT ``` ### AuthXClient Used for server-to-server identity operations. Typical operations include: ```python client.create_identity(...) client.get_by_id(...) client.get_by_email(...) client.get_by_sso(...) ``` The client communicates with AuthX internal endpoints using the configured service token. ### AuthXJWT Used by a consumer to verify AuthX-issued JWTs locally. Conceptually: ```text Consumer │ ├── AuthXClient │ └── HTTP → AuthX internal API │ └── AuthXJWT └── Local JWT verification ``` The Django client is therefore an optional convenience layer; it does not change AuthX's architecture or identity authority. --- ## 27. Django Consumer Integration When a Django application uses the optional client package, the normal architecture is: ```mermaid flowchart LR REQUEST["Django API Request"] AUTH["AuthXJWT"] MIRROR["Local Identity Mirror"] API["Django Application"] AUTHX["AuthX"] REQUEST --> AUTH AUTH -->|"Local verification"| API API --> MIRROR API -->|"Identity management"| AUTHX ``` The important distinction is: ```text JWT verification → local Identity management → AuthX HTTP API ``` A consuming application does not need to call AuthX for every bearer-token verification. --- ## 28. Identity Ownership Boundary The ownership model is central to AuthX's architecture. | Data / Capability | AuthX | Consumer | | -------------------- | -----------------: | ---------------------------: | | Identity ID | Owner | Reference | | Email | Owner | Mirror/reference as required | | Password | Owner | No ownership | | Password hash | Owner | Never receives | | SSO provider linkage | Owner | Reference | | Authentication | Owner | Consumer trusts AuthX | | JWT signing | Owner | No | | JWT verification | Provides authority | Performs verification | | Application profile | No | Owner | | Application roles | No | Owner | | Domain entities | No | Owner | | Organization data | No | Owner | This prevents identity responsibilities from leaking into consuming applications. --- ## 29. Configuration Architecture AuthX is configured through environment variables. Configuration areas include: ```text Application APP_ENV APP_HOST APP_PORT APP_BASE_URL Database DATABASE_URL DATABASE_URL_SYNC POSTGRES_USER POSTGRES_PASSWORD POSTGRES_DB JWT JWT_PRIVATE_KEY JWT_PUBLIC_KEY JWT_ALGORITHM JWT_ACCESS_TOKEN_EXPIRE_MINUTES JWT_REFRESH_TOKEN_EXPIRE_DAYS JWT_ISSUER JWT_AUDIENCE Internal Authentication AUTHX_SERVICE_TOKEN CORS CORS_ORIGINS ``` `JWT_ISSUER` and `JWT_AUDIENCE` are required rather than silently using DjangoPlay-specific defaults. The issuer is validated as an HTTP(S) URL and production requires HTTPS. --- ## 30. AuthX Service URL vs JWT Issuer These concepts must remain separate. ### `APP_BASE_URL` Describes where the AuthX service is reachable. Example: ```text http://127.0.0.1:8100 ``` ### `JWT_ISSUER` Describes the identity authority asserted inside the JWT. Example: ```text https://auth.example.com ``` Therefore: ```text APP_BASE_URL │ └── Network/service location JWT_ISSUER │ └── Identity authority ``` They may intentionally differ. --- ## 31. CORS Architecture AuthX supports explicit CORS configuration through: ```text CORS_ORIGINS ``` This is intended for browser-based consumers that need cross-origin access. The production configuration should contain only the browser origins that actually require access. CORS is separate from backend service authentication: ```text CORS └── Browser origin policy X-Service-Token └── Backend service authentication ``` A valid CORS origin does not grant access to internal identity-management operations. --- ## 32. Security Boundaries AuthX contains several explicit trust boundaries. ```mermaid flowchart TB UNTRUSTED["Untrusted Client"] PUBLIC["Public OIDC API"] AUTHX["AuthX"] INTERNAL["Internal API"] SERVICE["Trusted Backend"] PRIVATE["JWT Private Key"] PUBLICKEY["JWKS / Public Key"] DB[("AuthX PostgreSQL")] UNTRUSTED --> PUBLIC PUBLIC --> AUTHX SERVICE -->|"X-Service-Token"| INTERNAL INTERNAL --> AUTHX AUTHX --> PRIVATE AUTHX --> DB AUTHX -->|"Signed JWT"| UNTRUSTED UNTRUSTED -->|"JWT verification"| PUBLICKEY ``` The critical boundaries are: 1. Client → public API 2. Trusted backend → internal API 3. AuthX → database 4. AuthX private signing key → signed JWT 5. Consumer → JWT verification 6. Consumer → application authorization --- ## 33. Request Processing Model The general AuthX request path is: ```text HTTP Request │ ▼ FastAPI │ ▼ API Endpoint │ ├── Public OIDC request │ └── Internal identity request │ ▼ Validation / Authentication │ ▼ Service Layer │ ▼ Database / Security Operations │ ▼ Response ``` The service layer is the main boundary for identity operations. --- ## 34. Middleware and Operational Concerns AuthX contains middleware and logging components separate from its domain services. This allows cross-cutting concerns such as request logging and operational instrumentation to remain outside individual endpoint implementations. Conceptually: ```text Request │ ▼ Middleware │ ▼ FastAPI Router │ ▼ Endpoint │ ▼ Service ``` Logging should not change the identity or authorization semantics of the request. --- ## 35. Database Migration Architecture AuthX uses Alembic for database schema migrations. The migration path is separate from normal runtime database access. ```text AuthX Source │ ▼ Alembic │ ▼ AuthX PostgreSQL Schema ``` The service uses: ```text DATABASE_URL ``` for asynchronous application database access and: ```text DATABASE_URL_SYNC ``` for synchronous migration/tooling operations. This separation is reflected in the AuthX configuration and deployment model. --- ## 36. Deployment Architecture AuthX is designed to run as an independent service. A typical deployment is: ```mermaid flowchart TB EDGE["Reverse Proxy / Load Balancer"] AUTHX1["AuthX Instance"] DB[("PostgreSQL")] EDGE --> AUTHX1 AUTHX1 --> DB ``` For a simple deployment: ```text Reverse Proxy │ ▼ Uvicorn / AuthX │ ▼ PostgreSQL ``` For larger deployments: ```mermaid flowchart TB LB["Load Balancer"] A1["AuthX Instance 1"] A2["AuthX Instance 2"] A3["AuthX Instance N"] DB[("PostgreSQL")] LB --> A1 LB --> A2 LB --> A3 A1 --> DB A2 --> DB A3 --> DB ``` Because access-token verification is based on signed JWTs rather than server sessions, AuthX instances can independently process token operations. However, refresh-token state remains shared through the AuthX database. --- ## 37. Stateless and Stateful Components AuthX deliberately combines stateless and stateful mechanisms. | Component | State Model | Reason | | ---------------------- | ------------------- | ---------------------------------- | | Access JWT | Stateless | Fast local verification | | JWT signature | Stateless | Public-key verification | | JWKS | Public metadata | Key distribution | | Identity | Stateful | Authoritative identity persistence | | Password hash | Stateful | Credential persistence | | Refresh token | Stateful | Rotation and revocation | | Internal service token | Configuration state | Backend trust | This hybrid model provides both scalability and revocation capabilities. --- ## 38. Horizontal Scaling Considerations AuthX's architecture supports horizontal scaling of the API layer. ```text Load Balancer │ ┌────────────┼────────────┐ │ │ │ ▼ ▼ ▼ AuthX-1 AuthX-2 AuthX-3 │ │ │ └────────────┼────────────┘ ▼ PostgreSQL ``` All instances must share the same logical identity authority and compatible configuration, including: * JWT issuer * JWT audience * JWT signing key material * Database * Internal service credential policy JWT signing configuration is particularly important: consumers must be able to verify tokens issued by any active AuthX instance. --- ## 39. Key Management AuthX uses an RSA key pair. ```text JWT_PRIVATE_KEY │ └── AuthX only JWT_PUBLIC_KEY │ └── Consumer verification ``` The private key must never be: * committed to source control * included in container images unnecessarily * returned through an API * provided to consuming applications The public key can be distributed through: ```http GET /jwks ``` or configured directly in a consumer where supported. A new deployment should generate a fresh key pair rather than reusing an exposed key. --- ## 40. API Schema Boundaries AuthX intentionally separates internal and public response schemas. ```text Internal Identity Response │ ├── email ├── username ├── SSO information ├── status flags ├── timestamps └── identity metadata Public Userinfo Response │ ├── sub ├── email ├── email_verified └── preferred_username ``` Sensitive credential information is excluded from both. This prevents internal identity-management data from automatically becoming public authentication data. --- ## 41. Error and Validation Boundaries AuthX uses API-level validation before identity operations are executed. Typical examples include: ```text Invalid UUID │ ▼ Request validation │ ▼ HTTP 422 ``` Authentication failures are handled separately: ```text Invalid credentials │ ▼ Authentication failure │ ▼ HTTP 401 ``` Internal service authentication failures are distinct: ```text Invalid X-Service-Token │ ▼ Internal authorization failure │ ▼ HTTP 403 ``` This separation is useful operationally because it distinguishes: * malformed requests * failed user authentication * failed backend authentication --- ## 42. Health Architecture AuthX exposes: ```http GET /health ``` The endpoint is intended for operational health checks. Logical response: ```json { "status": "ok", "service": "authx" } ``` A reverse proxy, process manager, container platform, or monitoring system can use this endpoint to determine whether the service is responding. --- ## 43. End-to-End Authentication Flow The complete authentication lifecycle can be summarized as: ```mermaid sequenceDiagram participant U as User / Client participant A as AuthX participant DB as PostgreSQL participant C as Consumer Application U->>A: Authenticate A->>DB: Load identity DB-->>A: Identity + credential state A->>A: Verify credentials A->>A: Create signed JWT A->>DB: Store refresh-token state A-->>U: Access + Refresh JWT U->>C: Bearer Access JWT C->>C: Verify signature locally C->>C: Validate issuer / audience / expiry C-->>U: Authorized application response ``` AuthX therefore remains out of the hot path for normal access-token verification. --- ## 44. Refresh Lifecycle ```mermaid sequenceDiagram participant C as Client participant A as AuthX participant DB as PostgreSQL C->>A: Refresh token A->>A: Validate JWT A->>DB: Lookup jti DB-->>A: Refresh state alt Valid A->>DB: Revoke old refresh token A->>A: Issue new access token A->>A: Issue new refresh token A->>DB: Persist new refresh state A-->>C: New token pair else Revoked / Expired A-->>C: Reject refresh request end ``` --- ## 45. Identity Lifecycle ```mermaid flowchart TD CREATE["Create Identity"] ACTIVE["Active Identity"] UPDATE["Update Identity"] LOGIN["Authenticate"] SOFT["Soft Delete"] INACTIVE["Inactive / Deleted"] CREATE --> ACTIVE ACTIVE --> UPDATE UPDATE --> ACTIVE ACTIVE --> LOGIN ACTIVE --> SOFT SOFT --> INACTIVE ``` The identity remains persisted after soft deletion but is excluded from normal authentication and lookup behavior. --- ## 46. Architecture Responsibilities AuthX is responsible for: * Identity persistence * Credential management * Password hashing * Authentication * SSO identity association * Identity lifecycle * JWT issuance * JWT signing * Refresh-token rotation * Refresh-token revocation * OIDC discovery * JWKS publication * Userinfo * Trusted backend identity-management APIs Consumers are responsible for: * Application profiles * Application/domain data * Application-specific authorization * Organization membership * Business rules * Resource ownership * Application UI/API behavior * Local JWT verification This separation is fundamental to the architecture. --- ## 47. What AuthX Does Not Own AuthX intentionally does not attempt to become a general application database. It does not own: ```text Customer profiles Organizations Teams Invoices Projects Business entities Application permissions Application workflows Application-specific domain data ``` A consuming application should not place these responsibilities into AuthX merely because AuthX provides the identity. The intended relationship is: ```text AuthX └── "Who is this identity?" Consumer └── "What can this identity do in my application?" ``` --- ## 48. Security Model Summary The complete security model can be summarized as: ```text AuthX │ ┌────────────┼────────────┐ │ │ │ ▼ ▼ ▼ Credentials JWTs Identity DB │ │ │ │ │ │ ▼ ▼ ▼ Password RS256 PostgreSQL Hashing Signing │ ▼ Public JWKS │ ▼ Consumers ``` The most important security properties are: 1. Credentials remain inside AuthX. 2. JWT private keys remain inside AuthX. 3. Consumers receive only public verification material. 4. Access tokens can be verified locally. 5. Refresh tokens have server-side revocation state. 6. Internal identity APIs require backend authentication. 7. Public identity responses expose only required information. 8. Consumer authorization remains outside AuthX. --- ## 49. Architectural Benefits This architecture provides several important benefits. #### Centralized Identity Multiple applications can share the same identity authority. #### Reduced Credential Duplication Applications do not need independent password stores. #### Local JWT Verification Consumers can authenticate requests without an AuthX network round-trip for every request. #### Controlled Internal Access Identity-management operations are separated from public authentication. #### Independent Application Evolution Consumers can evolve their own domain models without modifying AuthX. #### Horizontal API Scaling Multiple AuthX instances can serve authentication traffic while sharing the same identity persistence layer. #### Clear Security Boundaries Private signing material, credentials, identity persistence, and application authorization have explicit ownership boundaries. --- ## 50. Reference Architecture The complete AuthX architecture can be summarized as: ```mermaid flowchart TB CLIENT["Clients
Browser / Mobile / CLI / API"] subgraph AX["AuthX Identity Service"] API["FastAPI"] OIDC["Public OIDC API"] INTERNAL["Internal Identity API"] SERVICE["Identity Service"] SECURITY["Security / JWT"] MODELS["UserIdentity"] REFRESH["RefreshToken"] CONFIG["Configuration"] end DB[("AuthX PostgreSQL")] subgraph CONSUMERS["Consumer Applications"] APP1["Application A"] APP2["Application B"] APP3["Application N"] end CLIENT --> OIDC OIDC --> SECURITY OIDC --> SERVICE INTERNAL --> SERVICE SERVICE --> MODELS SERVICE --> REFRESH MODELS --> DB REFRESH --> DB SECURITY -->|"RS256 JWT"| CLIENT CLIENT -->|"Bearer JWT"| APP1 CLIENT -->|"Bearer JWT"| APP2 CLIENT -->|"Bearer JWT"| APP3 APP1 -->|"X-Service-Token"| INTERNAL APP2 -->|"X-Service-Token"| INTERNAL APP3 -->|"X-Service-Token"| INTERNAL CONFIG --> API CONFIG --> SECURITY CONFIG --> DB ``` --- ## 51. Final Architecture Statement AuthX is a **standalone identity authority**, not an authentication library embedded inside a single application. Its architecture separates: ```text Identity │ ├── Credentials ├── Authentication ├── SSO └── Identity Lifecycle Tokens │ ├── JWT Issuance ├── JWT Signing ├── JWKS └── Refresh Rotation Persistence │ ├── UserIdentity └── RefreshToken Integration │ ├── Public OIDC API ├── Internal Identity API └── Consumer Client Security │ ├── Password Hashing ├── RSA Signing ├── Issuer / Audience Validation └── Backend Service Authentication ``` The resulting architecture allows AuthX to act as a reusable identity platform for Django applications, APIs, mobile backends, command-line applications, and other systems without making any individual consumer the owner of identity. DjangoPlay is one consumer of this architecture; AuthX itself remains consumer-independent.