2 Commits

Author SHA1 Message Date
3c633e5ebd §9 JWT signing-key rotation runbook (todo §9); turned the README's 3-line rotation note into an operational runbook and closed the tooling gap that made its documented steps unrunnable — the old "prepend a key / drop it later" meant hand-editing a JSON file holding a private signing key. Tests-first: new pure rotateJwks(current,{prune}) in gen-jwks.ts — --prepend puts a fresh ES256 key first (Kratos signs with keys[0], the old keys still verify in-flight JWTs) and keeps the rest in order; --prune keeps only the newest (drop superseded post-TTL). CLI reads the existing set from a path arg and writes the new set to stdout (header documents the temp-file redirect so the shell's > can't truncate the input). gen-jwks.test.ts covers prepend (length+1, fresh kid first, old set preserved) + prune (→ 1 key). Runbook documents the two-sided install (Kratos signer env/mount + web JWKS_URL; file:// hot-reloads, base64:// immutable), why it's zero-downtime (sign-with-first + verify-by-kid), the scheduled path (prepend → restart kratos → verify new kid → wait ~12min = 10m TTL + skew → prune; rollback before prune) and the emergency path (replace with a single key → every leaked-key token fails signature → forced re-login; the §9 denylist is moot since the signature is already invalid). Verified the CLI live against the committed dev JWKS (bare→1, --prepend→2 with old kid second, --prune→1); jwks.json untouched. Docs/CLI-only, covered by units (per the §9 precedent, no new browser E2E). README Status + Layout updated. typecheck + 335 units green (333 → 335). 2026-06-20 15:54:17 +02:00
6640dfc84e Generate + mount the JWT signing JWKS (todo §3); ES256 gen-jwks tool, committed dev key, key-rotation docs 2026-06-17 13:24:31 +02:00