Files
dsh-web/internal/api/AUTH_DESIGN.md
T

23 lines
1.5 KiB
Markdown

# Authentication boundary (§13)
- Real logins retain `dsh_session` as 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 a 24-hour absolute lifetime.
Conditional SQL update makes rotation single-use even across concurrent requests.
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.