Key hierarchy
How secret values are encrypted, where the master key is kept, and what losing it means.
Two levels of keys
- Each value is encrypted with AES-256-GCM. The ciphertext is bound to its vault, secret and version, so it cannot be moved to another secret.
- Each vault has its own data key. It is stored encrypted — wrapped with the master key —
in the Kubernetes Secret
sv-keys-<vault>in the vault's namespace, never in the database. - The master key (key encryption key) is a Kubernetes Secret named
stackship-secrets-kekinstackship-system, data keykey: 32 random bytes, base64-encoded.
The database holds metadata and ciphertext only.
The master key
The installer creates the master key on first installation and never replaces an existing one.
The Secrets service checks it when it starts and refuses to start when the Secret is missing,
has no key, or holds a key that is not 32 bytes or looks weak (for example printable text or
too little variation); the log then says what is wrong. On success it logs the key's
fingerprint as sha256:…, which lets you confirm that two installations use the same key
without revealing it.
The service keeps the master key in memory for as long as it runs, and unwrapped vault keys for five minutes.
Rotation
Neither key can be rotated today. Replacing the master key makes every existing vault unreadable, and the service refuses to create a vault key where one already exists.
Back up the master key
Without the master key no vault can be read. Keep a copy of stackship-secrets-kek outside the
cluster, stored as carefully as the secrets themselves. A restored platform must get back the
same master key: the vault keys in the sv-keys-* Secrets can only be unwrapped with it.