# JWT Authentication

## Overview
JWT-based authentication with {{algorithm}} signing, access tokens valid for {{access_token_ttl}}, refresh tokens valid for {{refresh_token_ttl}}, and token rotation on refresh.

## Acceptance Criteria

### AC-1: Login
- Accept `email` and `password` credentials
- Issue a signed access token ({{algorithm}}, TTL {{access_token_ttl}}) and refresh token (TTL {{refresh_token_ttl}})
- Return tokens in the response body; set refresh token as `HttpOnly` cookie

### AC-2: Token Verification
- Validate signature, expiry, and issuer on every protected route
- Return 401 with a clear message when token is expired or invalid
- Extract user claims (id, role, email) from token without a database lookup

### AC-3: Token Refresh
- Accept refresh token from `HttpOnly` cookie
- Issue new access and refresh tokens (rotation)
- Blacklist the previous refresh token to prevent reuse

### AC-4: Logout
- Blacklist the current refresh token on logout
- Clear the `HttpOnly` cookie
- Return 204 on success

### AC-5: Token Blacklist
- Store blacklisted token JTIs in a fast store (Redis recommended)
- Entries expire automatically at token TTL to prevent unbounded growth

## Technical Notes
- Never store the raw JWT secret in application code — use environment variables
- Include `jti` (JWT ID) claim for blacklist lookups
- Rotate signing keys on a quarterly schedule
