Credential Encryption
For: Platform engineers and security teams evaluating the data-at-rest security model for inline AI provider credentials.
Security Overview | mTLS | Bundle Signing | Credential Encryption
Axemere encrypts AI provider API keys before they are stored in the database using envelope encryption: a fresh key generated per credential, wrapped by a dedicated Cloud KMS key that never leaves KMS. A database backup, stolen snapshot, or SQL injection attack yields only ciphertext, and unwrapping it requires a live KMS call, not just database access.
Table of Contents
- What Is Encrypted
- How Envelope Encryption Works
- Encryption Flow
- Decryption Flow
- Credential Modes and Encryption Scope
- Threat Model
- See Also
What Is Encrypted
| Credential mode | What is stored in DB | Encrypted? |
|---|---|---|
inline | Actual AI provider API key | Yes — AES-256-GCM |
alias | Name of an environment variable (e.g. OPENAI_API_KEY) | No — not a secret |
byok | Empty: caller supplies the key at request time | N/A |
Only inline mode stores a real secret in the database. alias and byok modes do not need encryption because no secret is persisted.
How Envelope Encryption Works
Axemere uses genuine envelope encryption: a fresh, random 256-bit key (the DEK, data encryption key) is generated for every credential and used to encrypt it locally with AES-256-GCM (NIST SP 800-38D). The DEK itself is then wrapped by a call to a dedicated Cloud KMS key (the KEK, key encryption key) that never leaves KMS: never in an environment variable, never in the control plane's process memory outside the moment of a wrap/unwrap call, never readable by anyone with database or pod access alone.
Self-hosted and other-cloud deployments, not yet covered by this Cloud KMS integration, use a simpler fallback: direct AES-256-GCM encryption under a single platform-held key. That fallback still yields only ciphertext from a database backup or SQL injection, but the key itself is held directly rather than in a hardware-backed KMS, a weaker guarantee against an attacker with broader infrastructure access. The managed, GCP-hosted control plane runs the Cloud KMS-backed version described above.
Encryption Flow
When an inline credential is registered via the admin API or console:
- The control plane receives the plaintext API key.
- A fresh, random 256-bit DEK is generated for this credential.
- AES-256-GCM encrypts the value locally with the DEK.
- The DEK is wrapped with a single Cloud KMS call against the dedicated KEK, then discarded from memory.
- The wrapped DEK and the ciphertext are stored together in the database; no plaintext, and no unwrapped DEK, ever reaches storage.
Decryption Flow
When a gateway requests its credential set from the control plane:
- The control plane reads the stored encrypted value.
- The wrapped DEK is unwrapped with a Cloud KMS call (a short-lived, TTL'd in-process cache avoids a KMS round trip on every request for the same credential).
- AES-256-GCM decrypts the value locally with the unwrapped DEK.
- The plaintext API key is returned to the gateway over mTLS; it is never stored or logged by the control plane.
In steady state, every inline credential uses this envelope-encrypted format once the Cloud KMS integration is configured: migration to it runs automatically and idempotently on every control plane startup. A simpler, legacy decrypt path remains in the code as a defensive fallback for a narrow migration-time edge case (a KMS call failing mid-migration on one credential, before the next startup retries it), not because residual legacy-encrypted credentials are expected to persist.
Credential Modes and Encryption Scope
Threat Model
| Threat | Mitigated? | Notes |
|---|---|---|
| Database backup / dump theft | Yes | Only ciphertext and a wrapped key are in the database; nothing there alone decrypts it |
| Misconfigured DB IAM | Yes | Same — ciphertext and a wrapped key only |
| SQL injection on CP DB | Yes | Only ciphertext and a wrapped key reachable |
| Compromised CP process memory | No | Plaintext in memory during request lifecycle |
| Compromised gateway process memory | No | Gateway receives plaintext over mTLS for use in outbound requests |
| mTLS interception | No | Separate concern: see mTLS guide |
| Insider with CP database access but no KMS decrypt permission | Yes | The wrapping key never leaves Cloud KMS; database access alone can't unwrap a credential |
| Insider with both CP infra access AND KMS decrypt permission on the wrapping key | No | Full customer-managed CMEK (a key we never have standing access to) is still future work |
Envelope encryption protects the database at rest, and narrows who can decrypt it: unlike a static platform key, unwrapping a credential now requires a live, audited Cloud KMS call against a specific key, not just database access. It does not protect in-flight data or process memory, and it does not yet protect against someone with both infrastructure and the relevant KMS permissions. That's the correct and intended scope today, with full CMEK as the next step.