# SPEC — F-005 Identity: register, login, sessions

## Problem
Customers need accounts; nothing trusts who calls the API.

## Goal
Registration, login, logout with hashed passwords and secure sessions — server is the
only authority for identity (never trust the frontend).

## Scope IN
- `src/modules/identity` with hexagonal layers: domain / application / infrastructure / api
- Register, login, logout use cases over PostgreSQL (source of truth)
- Argon2id password hashing (OWASP parameters)
- Server-side opaque sessions stored in DB; cookie carries a random token, DB stores only its SHA-256 hash
- Secure session cookie: HttpOnly, Secure, SameSite
- Login rate limiting (10 consecutive failures -> 429 with cooldown) behind an interface
- Migration 002_identity (identity_users, identity_sessions) with down
- Config: COOKIE_SECURE flag (default true)

## Scope OUT
- No MFA, no OAuth providers, no profile editing
- No email verification flow, no password reset
- No distributed rate limiting (in-memory per instance; documented)
- No expired-session sweeper (follow-up)

## Acceptance criteria
1. Given valid credentials When login Then HTTP 200 and secure session cookie set.
2. Given wrong password When login Then HTTP 401 and no user enumeration hint (unknown email returns the identical 401).
3. Passwords stored with argon2, never plaintext or reversible.
4. Given 10 failed logins in a row When next login attempted Then HTTP 429.
5. Session cookie is HttpOnly, Secure and SameSite.
6. `./scripts/verify.sh` green.

## Dependencies added
- argon2 (canonical Argon2id implementation; PHC string output)
- @fastify/cookie (explicit setCookie/clearCookie; official Fastify plugin)
Justification goes to `spec/tech.md`.
