ADR-0003: Auth Adapter and Session Token Model
- Status: Accepted
- Date: 2026-04-10
Context
The project must avoid identity-provider lock-in while enforcing short-lived sessions, offline-aware behavior, and re-authentication for protected submissions after expiry.
Decision
Adopt a provider-agnostic auth adapter with OIDC-compatible semantics as the baseline integration contract.
Session model:
- server-issued access token with 24-hour baseline TTL
- local session snapshot includes user ID, role, issuedAt, expiresAt, and state
- protected actions require active session validation
- after expiry, app may allow read-only local view but must block protected submission until re-authentication
- unsynced queue is retained across expiry and submitted only after successful re-authentication
Boundary rules:
- auth implementation must be encapsulated behind module interface
- UI must not depend on provider-specific SDK types
- session checks enforced in both client guards and backend authorization
Consequences
Benefits:
- provider swap is feasible without rewriting app shell
- aligns with least privilege and expiry requirements
- predictable user recovery path after offline expiry
Tradeoffs:
- requires adapter maintenance and contract tests
- requires careful token refresh and clock-skew handling
Alternatives Considered
- hard binding to single vendor auth SDK: rejected due to lock-in risk
- long-lived non-expiring sessions: rejected due to security and compliance risk
- fully offline auth without server validation: rejected for protected action security
References
- ../../product/prd.md
- ../srs.md
- ../sdd.md
- ../../reference/api/api-contract.md
- Requirement IDs: FR-016, FR-017, SCR-001, SCR-002, SCR-003, SCR-004, NFR-009
Addendum — 2026-06-10
The current implementation (AuthContext.tsx, 642 lines in a single React Context) violates the "encapsulated behind module interface" rule. Refactor #39 splits the auth logic into discrete modules (sessionManager, sessionHydrator, keyRotationService) with explicit interfaces, finally fulfilling the ADR's original intent. Refresh token rotation is already implemented and preserved.