Master encryption key
ValkyrieID encrypts secrets stored in the database with a master key:
- ASP.NET Data Protection keys (used for cookies and anti-forgery tokens)
- signing keys, TOTP secrets, and the SMTP password (in later releases)
Secrets are encrypted with AES-256-GCM. The master key is never stored in the database.
Back up the master key
A database backup is useless without the master key that encrypted it. Store the key in a secret manager and back it up together with, but separately from, the database.
Generate a key
The key is 32 random bytes, base64 encoded:
openssl rand -base64 32PowerShell 7+:
$b = [byte[]]::new(32); [Security.Cryptography.RandomNumberGenerator]::Fill($b); [Convert]::ToBase64String($b)Supply it as MasterKey__Current (environment variable) or MasterKey:Current (configuration). Prefer environment variables or a secret store over committing it to appsettings.json.
Rotate the key
Generate a new key.
Set the new key as
MasterKey:Currentand move the old key toMasterKey:Previous:0.Restart all instances.
Re-encrypt the stored secrets with the new key:
sh./valkyrieid admin reencryptConfirm nothing uses the old key any more:
sh./valkyrieid admin reencrypt --check # exit code 0 when doneRemove
MasterKey:Previous:0and restart all instances.
New secrets are encrypted with the current key, and existing secrets can still be decrypted with a previous key until step 4 has run. admin reencrypt runs in a single database transaction and is safe to repeat. It fails, without changing anything, if some data was encrypted with a key that isn't configured.
Run step 4 after every instance uses the new key (step 3), so no instance writes new secrets with the old key in the meantime.