# ADR 0002: Session-based authentication with HttpOnly cookies

## Status

Accepted — 2026-06-26

## Context

Phase 1 requires secure user authentication without binding to external identity providers. The web app (Next.js) and API (NestJS) run on different origins in development (`localhost:3000` / `localhost:3001`) but share credentials via CORS.

## Decision

- Use opaque session tokens (32 random bytes), stored as SHA-256 hash in `UserSession`.
- Deliver sessions via HttpOnly cookie `hgc_session` with `SameSite=lax` and `Secure` in production.
- Password hashing with Argon2id via `@node-rs/argon2`.
- TOTP 2FA with `otplib`; recovery codes stored hashed.
- Login challenges for 2FA stored in Redis (5 min TTL).
- Transactional emails via BullMQ `notifications` queue processed by worker + SMTP.

## Consequences

- Browser clients must use `credentials: 'include'`.
- API CORS must allow `APP_URL` with credentials.
- Session revocation is immediate via DB `revokedAt`.
- No JWT in localStorage (reduces XSS token theft risk).

## Alternatives considered

- JWT in Authorization header — rejected for Phase 1 due to refresh complexity and XSS exposure in SPA storage.
- External auth (Auth0, Clerk) — rejected per product requirements.
