ADR-0008: Encryption key rotation and data retention ​
Status: accepted (2026-10-12)
Key rotation ​
- Ciphertexts use format v2: version byte, 4-byte key id (first bytes of SHA-256 of the key-encryption key), wrapped data key, encrypted payload. Format v1 (no key id) remains readable.
QUAVON_ENCRYPTION_KEYis the current key;QUAVON_PREVIOUS_ENCRYPTION_KEYS(comma-separated,*_FILEsupported) lists keys being rotated out. New data is always encrypted with the current key; decryption accepts any configured key.- Rotation procedure: generate a new key, move the old key to
QUAVON_PREVIOUS_ENCRYPTION_KEYS, set the new key, restart, runkeys rotate, checkkeys statusshows no remaining data on old keys, then remove the old key and restart. keys rotatere-wraps only the data keys (Cipher.rewrap), so payloads are not re-encrypted. Every encrypted column is listed in one registry, so new encrypted columns cannot be forgotten. Valkey caches (installation tokens, ETags) expire on their own and are not rotated.
Retention ​
- Daily
retentionmaintenance task. Defaults, overridable in instance settings:retention.webhookPayloadDays(14): webhook payloads are set to null; delivery rows stay for idempotency.retention.outboxDays(7): dispatched outbox rows are deleted.- Expired sessions and used or expired setup/break-glass tokens are deleted one day after expiry.
llm_callsfollowtenants.data_retention_days.
- The audit log is append-only and not subject to automatic retention until a policy is agreed with counsel.