--- id: specify-key-rotation-protocol name: Specify secret key rotation protocol and multi-key format status: completed depends_on: [] scope: narrow risk: critical impact: component level: implementation --- ## Description Lazy re-encryption in `services.md:94-97` is insufficiently specified for a security-critical operation: 1. `HUB_ENCRYPTION_KEY` (singular env var) — how are old and new keys stored simultaneously during rotation? 2. If process crashes between decrypt and re-encrypt-update, is the secret left in the old key version? 3. What happens if a secret with `keyVersion=1` is accessed after the old key is removed? Permanent data loss. 4. No background sweep — old-key-version secrets persist indefinitely. If old key is compromised, those secrets remain vulnerable. ## Acceptance Criteria - [ ] `services.md` specifies multi-key storage format: e.g., `HUB_ENCRYPTION_KEYS=v1:base64key,v2:base64key` or a key file - [ ] The re-encryption transaction is documented: decrypt → encrypt → UPDATE in a single DB transaction, with crash-safety note - [ ] A warning about the vulnerability window is added: old-key secrets not yet re-encrypted are at risk if old key is compromised - [ ] Decision documented: whether a background re-encryption sweep is required or deferred - [ ] Error handling for missing key version is documented: log error, skip re-encryption, alert operator ## References - docs/reviews/storage-architecture-review-2026-04-21.md#C11 - docs/architecture/storage/services.md:94-97 - docs/decisions/ADR-008 ## Notes > To be filled by implementation agent ## Summary > To be filled on completion