AuthX — Data Model
AuthX uses a relational persistence model centered around the authenticated identity.
On this page ▾
1. Overview
The persistence layer separates:
- User identity
- Refresh-token state
- Authentication lifecycle state
- Token revocation state
The identity record is the primary source of truth for authentication, while refresh tokens provide the server-side state required for token rotation and revocation.
Access tokens remain stateless and are not persisted.
2. Persistence Model
The core persistence relationship is:
UserIdentity
│
│ 1
│
│ N
▼
RefreshToken
`At a high level:
┌─────────────────────────────┐
│ UserIdentity │
│ │
│ Identity / Credentials │
│ Account State │
│ Verification State │
│ SSO Identity │
│ Login Metadata │
└──────────────┬──────────────┘
│
│ 1 : N
▼
┌─────────────────────────────┐
│ RefreshToken │
│ │
│ Token Identity │
│ JWT ID (JTI) │
│ Revocation State │
│ Expiration │
│ Creation Metadata │
└─────────────────────────────┘3. UserIdentity
UserIdentity represents the authenticated identity managed by AuthX.
It is the primary authentication record and acts as the identity source of truth.
Core Identity Data
Typical identity attributes include:
id
email
usernameCredential Data
password_hashThe password is never stored as plaintext.
The stored password representation is used by the configured password-verification mechanism.
SSO Identity
SSO-linked identities are represented through:
sso_provider
sso_idThis allows an identity to be associated with an external identity provider.
Account State
The identity also maintains account and verification state:
is_active
is_verified
is_staff
is_superuserLifecycle Metadata
created_at
updated_at
deleted_at
last_logindeleted_at supports the identity lifecycle without requiring immediate physical deletion of the underlying record.
4. UserIdentity Indexing
Identity lookups are optimized around the fields used by authentication and SSO workflows.
Important indexes include:
email
sso_provider + sso_id
is_active + deleted_atThe exact database index definition is owned by the AuthX migrations and should be treated as the authoritative schema.
5. RefreshToken
RefreshToken represents server-side refresh-token state.
Unlike access tokens, refresh tokens require persistence because AuthX must be able to determine whether a refresh token is still valid and whether it has been revoked.
Core fields include:
id
identity_id
jti
is_revoked
expires_at
created_at5.1 Identity Relationship
identity_id references:
user_identity.idThe relationship is:
UserIdentity
│
│ 1
│
│ N
▼
RefreshTokenAn identity can therefore have multiple refresh-token records.
This supports multiple sessions/devices and token rotation.
5.2 JWT ID (JTI)
The jti field stores the JWT ID associated with the refresh token.
It provides a server-side lookup key for refresh-token lifecycle operations such as:
- Token validation
- Rotation
- Revocation
- Session/token invalidation
5.3 Revocation
Refresh-token records contain:
is_revokedThis allows AuthX to invalidate a refresh token without relying exclusively on its expiration time.
A token can therefore be:
Valid
│
├── Not expired
└── Not revokedor:
Invalid
│
├── Expired
└── Revoked6. Token Persistence Model
AuthX intentionally uses different persistence strategies for access and refresh tokens.
Authentication
│
┌────────────┴────────────┐
▼ ▼
Access Token Refresh Token
│ │
▼ ▼
Stateless Stateful
│ │
Not persisted Database record
│
┌────────┼────────┐
▼ ▼ ▼
JTI Revoked ExpiryAccess Tokens
Access tokens are stateless.
They are not stored in the AuthX database.
Their validity is determined from the token itself and the configured authentication/verification rules.
Refresh Tokens
Refresh tokens are stateful.
They are persisted because AuthX needs server-side state for:
- Rotation
- Revocation
- Expiration tracking
- Token lifecycle management
7. Authentication Data Boundaries
The persistence model deliberately separates identity data from token lifecycle data.
┌───────────────────────────────────────┐
│ AuthX Identity │
│ │
│ UserIdentity │
│ ├── Identity │
│ ├── Credentials │
│ ├── SSO │
│ ├── Verification │
│ └── Account State │
│ │
│ │ │
│ │ 1:N │
│ ▼ │
│ RefreshToken │
│ ├── JTI │
│ ├── Revocation │
│ ├── Expiration │
│ └── Lifecycle │
└───────────────────────────────────────┘This separation prevents token lifecycle state from becoming part of the core identity record.
8. Data Lifecycle
A simplified identity lifecycle is:
Identity Created
│
▼
Email / Identity Verification
│
▼
Active Identity
│
├───────────────┐
▼ ▼
Authentication SSO Authentication
│ │
└───────┬───────┘
▼
Token Issuance
│
┌─────┴─────┐
▼ ▼
Access Token Refresh Token
Stateless Persisted
│
┌──────┴──────┐
▼ ▼
Rotate RevokeThe identity lifecycle and token lifecycle are therefore related but independently managed.
9. Soft Deletion
The identity model includes:
deleted_atThis allows AuthX to represent a deleted/deactivated identity without necessarily removing the database record immediately.
Authentication and identity lookups should respect the active/deleted state.
The combination of:
is_active
deleted_atallows the application to distinguish between account state and deletion lifecycle.
10. Data Integrity
The persistence layer should maintain the following invariants:
- Each
UserIdentityhas a unique identity record. - SSO identity mappings are uniquely identifiable by provider and provider-specific identity.
- Each
RefreshTokenbelongs to an existing identity. - Revoked refresh tokens cannot be used as valid refresh credentials.
- Expired refresh tokens cannot be used as valid refresh credentials.
- Access tokens do not require database persistence.
- Passwords are never persisted as plaintext.
Database constraints and migrations are the final authority for the exact implementation of these rules.
11. Security Considerations
Authentication data is security-sensitive.
The persistence layer therefore follows these principles:
- Passwords are stored only as password hashes.
- Plaintext passwords must never be persisted.
- Refresh-token state is persisted only where required for lifecycle control.
- Access tokens are not persisted.
- Token revocation state is maintained server-side.
- Authentication records should not be exposed through unrestricted APIs.
- Database credentials must remain outside source control.
- Sensitive authentication data must not be written to application logs.
12. Database Schema Ownership
The AuthX database schema is defined by the AuthX application's models and migrations.
This document describes the logical data model, not a replacement for the migration history.
When determining the exact current schema, use:
AuthX Models
│
▼
Django Migrations
│
▼
Database SchemaThe migration state should always be treated as authoritative for deployed environments.
13. Summary
AuthX's persistence model is centered around two core concepts:
| Model | Responsibility |
|---|---|
UserIdentity |
Authentication identity, credentials, SSO, account and lifecycle state |
RefreshToken |
Stateful refresh-token lifecycle, JTI, expiration and revocation |
The fundamental relationship is:
UserIdentity 1 ───────── N RefreshTokenAccess tokens remain stateless, while refresh tokens are persisted to support secure rotation and revocation.
This design keeps the identity model independent from token lifecycle state while providing AuthX with the server-side controls required for secure authentication.