Refresh Token
Data Entity
Description
Rotating refresh tokens that enable silent session renewal for mobile and web clients. Each token is single-use and rotates on every access-token refresh cycle. Issued by the Authentication Module; consumed by Mobile App (secure store) and Admin Web Portal (HTTP-only cookie). Bound to a user_session record for revocation.
Data Structure
| Name | Type | Description | Constraints |
|---|---|---|---|
id |
uuid |
Primary key | PKrequiredunique |
session_id |
uuid |
Foreign key to user_sessions — revoke session to invalidate all its refresh tokens | required |
token_hash |
string |
SHA-256 hash of the opaque token string. Raw token is never stored. | requiredunique |
family_id |
uuid |
Rotation family identifier. Reuse of any token in a family signals token theft and invalidates the entire family. | required |
client_type |
enum |
Client surface that holds this token — determines storage mechanism expectations | required |
issued_at |
datetime |
UTC timestamp when this token was issued | required |
expires_at |
datetime |
Absolute expiry — token is rejected after this time regardless of rotation state | required |
used_at |
datetime |
Timestamp when this token was consumed during a rotation. Null means unused. | - |
revoked_at |
datetime |
Timestamp of explicit revocation (sign-out, admin force-expire, theft detection). Null means active. | - |
revocation_reason |
enum |
Why this token was revoked | - |
ip_address |
string |
IP address from which this token was last used — for audit and anomaly detection | - |
user_agent |
string |
User-agent string recorded at issuance for security audit | - |
created_at |
datetime |
Record creation timestamp | required |
Database Indexes
idx_refresh_tokens_token_hash
Columns: token_hash
idx_refresh_tokens_session_id
Columns: session_id
idx_refresh_tokens_family_id
Columns: family_id
idx_refresh_tokens_expires_at
Columns: expires_at
idx_refresh_tokens_active_lookup
Columns: token_hash, revoked_at, used_at, expires_at
Validation Rules
token_hash_format
error
Validation failed
expires_at_in_future
error
Validation failed
session_exists
error
Validation failed
client_type_enum
error
Validation failed
revocation_reason_required_when_revoked
error
Validation failed
no_reactivation
error
Validation failed
Business Rules
single_use_rotation
A refresh token may only be consumed once. On valid use, it is marked used_at and a new token is issued in the same family. Subsequent use of an already-used token is treated as theft.
theft_detection_family_revocation
If a token that has already been used (used_at is set) is presented again, all tokens in the same family_id are immediately revoked with reason token_theft_detected, and the parent session is terminated.
session_cascade_revocation
Revoking a user_session (sign-out, admin force-expire, password change) must revoke all refresh tokens belonging to that session. Implemented via on_delete_cascade on session_id FK.
absolute_expiry_enforcement
A token is rejected if current time >= expires_at, regardless of whether it has been rotated before. Expiry is not extended on each use.
audit_all_revocations
Every revocation event (any revocation_reason) must be written to the audit log with actor, timestamp, reason, and session reference for the org's audit trail.
admin_forced_revocation
Organization Admins and Global Admins (with granted support access) can force-expire any session and its refresh tokens via Session Management. Every forced revocation is logged in the org's audit trail.
expired_token_cleanup
Tokens with expires_at older than 30 days and revoked_at set are eligible for hard deletion. A scheduled job purges them to keep the table bounded.