2.2 KiB
2.2 KiB
Authentication boundary (§13)
- Real logins retain
dsh_sessionas a database session binding and require a five-minute HS256 access JWT in an additional HttpOnly cookie. JWT verification fixes the algorithm and binds subject/session/issuer/audience/expiry. Bare session IDs never authenticate. Internal callers and test fixtures must also attach a signed access cookie. - Refresh is a random 256-bit HttpOnly cookie, scoped to
/api, with only its SHA-256 hash stored in SQLite. The session has an absolute lifetime configured by SESSION_TTL (default 24h), applied only to new logins. Session, refresh and CSRF cookies persist across browser restarts with explicit Max-Age/Expires bounded by that database expiry; rotation does not extend it. Transactional rotation stores current and previous token hashes. A keyed, session-bound successor derivation makes retries of the previous token return the same current token, including after response loss or server restart. Only one previous generation is accepted (until the next rotation or session expiry); this intentionally permits that generation to be replayed with the required session/Origin/CSRF checks. Older and unknown tokens are rejected. Plaintext refresh credentials are never stored. Logout deletes the database session and its refresh binding. Both refresh and logout retain mandatory exact Origin and session-bound CSRF checks, even when access has expired. Other operations require valid access. - Signing key is generated once under the configured data root, private mode 0600, and reused across restarts. Initialization errors fail authentication closed. Tokens never appear in JSON, URLs, audit detail, or application logs.
- Known accounts lock for 15 minutes after five failures; the counter/lock survive restart. Successful login resets the counter; expired locks reset the counter. Existing global throttling remains additional protection.
- Tests cover missing/tampered/expired access, database binding, refresh rotation and replay, CSRF/Origin rejection, logout revocation, key reuse/permissions, account isolation, restart persistence, lock expiry, and runtime compatibility.