docs: finalize demo session persistence
This commit is contained in:
@@ -9,18 +9,21 @@ The merchant dashboard needs simple username/password authentication for the hac
|
||||
|
||||
## Decision
|
||||
|
||||
Use cryptographically random opaque session tokens transported only in host-only `Secure`, `HttpOnly`, `SameSite=Lax` cookies. Store only a non-reversible token digest with server-side session state. Never place authentication tokens in local storage, session storage, URLs, or frontend-readable application state.
|
||||
Use 32-byte cryptographically random opaque session tokens transported only in a host-only `__Host-zpa_session` cookie with path `/`, no `Domain`, `Secure`, `HttpOnly`, and `SameSite=Lax`. Store sessions in PostgreSQL and persist only the SHA-256 token digest. Never place authentication tokens in local storage, session storage, URLs, frontend-readable application state, logs, or database columns.
|
||||
|
||||
Sessions expire after 12 hours of inactivity and no later than seven days after creation. Logout revokes the current session before clearing the cookie; disabling a merchant user revokes every active session for that user. Every protected HTTP request, SSE connection, and replay request resolves the merchant boundary from the current server-side session.
|
||||
|
||||
Persist activity at most once every five minutes. The idle timeout does not require per-request write precision, and coalescing avoids turning normal dashboard and SSE traffic into unnecessary PostgreSQL writes.
|
||||
|
||||
Passwords use Argon2id with unique salts and reviewed parameters. Expected login failures are externally generic. Demo credentials are generated through a one-time administrative workflow, displayed once, and never stored in Git or logs.
|
||||
|
||||
Demo usernames are stable lowercase `merchant-NNNN`-style identifiers with case-insensitive comparison. Failed logins are throttled by normalized username and source IP, return `429` with `Retry-After`, and never cause permanent account lockout. State-changing authenticated requests require CSRF tokens and strict same-origin evidence. A user may have at most two active sessions; a third successful login revokes the oldest.
|
||||
Demo usernames are stable lowercase `merchant-NNNN`-style identifiers with case-insensitive comparison. Failed logins default to five attempts per normalized username and 30 per source IP in five minutes, return `429` with `Retry-After`, and never cause permanent account lockout. State-changing authenticated requests require CSRF tokens and strict same-origin evidence. A user may have at most two active sessions; a third successful login revokes the oldest.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Logout, disablement, expiry, and incident response can invalidate access immediately.
|
||||
- The backend session store is on the protected-request path and must fail closed, be indexed, and have observable latency/availability.
|
||||
- A PostgreSQL outage also prevents authentication checks; this is preferable to trusting unverifiable client state, and no additional auth service is introduced for the demo.
|
||||
- SSE reconnect and replay must reauthorize instead of trusting a previous connection or event id.
|
||||
- Scaling API instances does not require sticky sessions when they share the approved authoritative session store.
|
||||
- Cookie scope, login-throttle thresholds, and the physical session-store contract remain explicit Identity-spec decisions rather than implicit framework defaults.
|
||||
|
||||
Reference in New Issue
Block a user