Skip to content

0004. JWT-based authentication with server-side revocation state

Status

Accepted (backfilled 2026-07-31; introduced with roadmap issue "phase-1-03 Auth router → DB + JWT" and extended by phase-4 hardening).

Context

A mobile client needs stateless request authentication that survives app restarts without a session store round-trip on every call, while the product's privacy posture demands the ability to revoke access and resist credential abuse.

Decision

Authenticate with JWTs issued by the backend auth router (backend/src/routers/auth.py) and managed on the client by an AuthContext (frontend/src/context/ — token storage and attachment to API calls). Keep the security-relevant state server-side in dedicated tables: revoked_token.py, login_attempt.py, password_reset_token.py, and auth_identity.py under backend/src/models/, with rate limiting (slowapi) and security-header middleware wired in backend/src/main.py.

Consequences

  • API requests are self-authenticating; the client persists the token and the auth context rehydrates it on launch.
  • Statelessness is deliberately compromised where it matters: token revocation and login-attempt throttling require DB lookups, trading pure JWT purity for the ability to lock out a compromised credential.
  • Password-reset and multi-identity flows have first-class storage rather than ad-hoc token columns.
  • Future auth changes (new identity providers, token rotation) must extend the models above rather than bypass them.