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