23 lines
1.5 KiB
Markdown
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.
|