You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Credential encryption key: keep it outside the catalog and add a rotation path #707
extenddb init generates the AES-256-GCM key that encrypts stored access key secrets and the secret keys of the temporary credentials AssumeRole issues. It stores the key, base64 encoded and not wrapped by any other key, as the encryption_key entry of the catalog's settings table (the settings collection on MongoDB) on all four backends. The server reads it from the catalog and caches it in memory.
The key and the ciphertext it protects are in the same database, so read access to the catalog, or to a catalog backup, yields every stored secret. There is no way to rotate the key: re-keying means re-creating the access keys. #228 documents this boundary in docs/manuals/10-security-model.md.
Request
Let the operator keep the key, or the key that wraps it, outside the catalog. Options named on #228:
wrap the key with an external key management service or an HSM, so the catalog holds only the wrapped key;
unwrap or derive it from a passphrase the operator supplies when the server starts;
a pluggable key provider, so a deployment can add its own.
Add a rotation path that re-encrypts the stored secrets under a new key without re-creating the access keys.
Questions for the design
Which providers come first, and where a provider is configured (extenddb.toml, the environment, a plugin).
What the server does when the provider cannot be reached at start-up, and whether it keeps caching the unwrapped key in memory.
How an existing deployment moves over: wrap the current key in place, or re-encrypt every secret.
How rotation treats secrets written while it runs, on each backend.
What backup and restore carry, and what a restore into another deployment needs.
This changes the on-disk format, so the pull request template asks for an RFC before the code.
The server reads encryption_key once at startup and keeps it in memory (crates/storage-postgres/src/lib.rs:949-964 on main at 4ee13f9). create_access_key encrypts with encryption_key (management_store/access_keys.rs:22), and is used by extenddb manage create-access-key (crates/app/src/manage_http.rs:290). So the only working rotation process is manual: replace the key in the catalog, restart every server, then re-create every access key. After the restart on, every previously existing access key and session credential will fail to decrypt. Each re-created key has a new access key ID and secret. So "re-keying means re-creating the access keys" is in practice an outage for every signed request, until each client has new credentials.
More questions for the design:
Should each stored secret record which key encrypted it (a key ID or version)? A server then knows which key to use, and a stopped rotation can resume.
How does each running server learn of the new key: a restart, a reload signal, or a poll of the catalog?
Should the decrypted secrets in each server's credential cache be flushed when the key changes?
Activity
refactor: move credential encryption and SigV4 onto aws-lc-rs (#776)
jcshepherd commentedon Nov 10, 2026
The server reads
encryption_keyonce at startup and keeps it in memory (crates/storage-postgres/src/lib.rs:949-964 on main at 4ee13f9).create_access_keyencrypts withencryption_key(management_store/access_keys.rs:22), and is used byextenddb manage create-access-key(crates/app/src/manage_http.rs:290). So the only working rotation process is manual: replace the key in the catalog, restart every server, then re-create every access key. After the restart on, every previously existing access key and session credential will fail to decrypt. Each re-created key has a new access key ID and secret. So "re-keying means re-creating the access keys" is in practice an outage for every signed request, until each client has new credentials.More questions for the design:
Should each stored secret record which key encrypted it (a key ID or version)? A server then knows which key to use, and a stopped rotation can resume.
How does each running server learn of the new key: a restart, a reload signal, or a poll of the catalog?
Should the decrypted secrets in each server's credential cache be flushed when the key changes?