Encryption Architecture
A technical deep dive into how your secrets are encrypted, stored, and protected at every layer.
Envelope encryption, explained simply
Direct encryption has a chicken-and-egg problem: to encrypt data, you need a key. Where do you store the key? If you store it alongside the data, anyone who breaches the database gets both. If you store it elsewhere, you need a key for the key.
Envelope encryption solves this with a two-layer approach:
ENVELOPE ENCRYPTION MODEL
LAYER 1 — Your Secret (plaintext)
"gemini-api-key-example" — the raw credential you want to protect
↓ encrypted with AES-256-GCM by DEK ↓
LAYER 2 — Data Encryption Key (DEK)
32-byte AES-256 key, randomly generated per secret. Never stored in plaintext. Stored encrypted by the KEK alongside the ciphertext.
↓ DEK wrapped (encrypted) by KEK via GCP KMS ↓
LAYER 3 — Key Encryption Key (KEK)
Per-tenant master key. Lives exclusively inside Google Cloud KMS. Never exported. Never touches our servers.
The key insight: the KEK never leaves Google's infrastructure. GCP KMS performs wrap/unwrap operations securely. Even a full breach of our database only yields encrypted blobs — useless without access to the KMS.
GCP KMS key hierarchy
GCP KMS HIERARCHY
Algorithm: AES-256-GCM (SYMMETRIC_ENCRYPTION)
Protection: SOFTWARE (Google Cloud KMS)
Rotation: 90-day automatic rotation
Key purpose: ENCRYPT_DECRYPT
Each tenant gets its own KEK in KMS, providing cryptographic tenant isolation. A compromised service account for one tenant cannot decrypt another tenant's secrets — the KMS IAM policies enforce this boundary.
Google Cloud KMS Security
Google Cloud KMS provides enterprise-grade key management with the following security guarantees:
Key isolation
Keys never leave Google's infrastructure; all cryptographic operations occur server-side.
Identity-based auth
IAM policies enforce strict access control; only authorized service accounts can use keys.
Key export prevention
Key material cannot be exported from KMS — ever. Only encrypt/decrypt operations are exposed.
Audit logging
Every KMS operation (wrap, unwrap, key rotation) is logged in GCP Cloud Audit Logs.
Store and retrieve flow
STORE (set_secret)
- 1API receives plaintext secret over TLS
- 2Generate 32-byte random DEK
- 3Encrypt secret with DEK (AES-256-GCM)
- 4Call GCP KMS CryptoKey.Encrypt(DEK)
- 5KMS returns wrapped DEK (never sees secret)
- 6Store [encrypted_secret + wrapped_DEK] in DB
- 7Plaintext secret is garbage-collected from memory
RETRIEVE (get_secret)
- 1Validate agent key / scoped token
- 2Check scope, TTL, IP allowlist, approvals
- 3Fetch [encrypted_secret + wrapped_DEK] from DB
- 4Call Google Cloud KMS CryptoKey.Decrypt(wrapped_DEK)
- 5KMS returns plaintext DEK (inside secure boundary)
- 6Decrypt secret with DEK (AES-256-GCM)
- 7Return plaintext secret over TLS; log access
What an attacker gets if the database is breached
Good news
A complete database dump is computationally uselessto an attacker without access to GCP KMS. Here's what they actually get:
| What's in the database | Is it useful to an attacker? |
|---|---|
| Encrypted secret ciphertext (AES-256-GCM) | No — without the DEK, it's random bytes |
| Wrapped DEK (AES-256-GCM encrypted by KMS KEK) | No — without KMS access, unwrapping is computationally infeasible |
| Secret metadata (path, tier, tags, description) | Partial — knows what secrets exist but not their values |
| Audit log entries | Partial — knows access patterns but not secret values |
| Tenant configuration (namespaces, policies) | Partial — operational data, no secret material |
| Password hashes (bcrypt + pepper) | Hardened — bcrypt with cost factor 12 + secret pepper |
Defense in depth
The encryption model assumes the database will eventually be breached — this is an industry-standard assumption. The encryption is designed such that a database breach is not a secret compromise event. You would still need to rotate secrets, but the encrypted values in the breach are worthless.
Key rotation
KEKs are automatically rotated every 90 days via GCP KMS automatic rotation policy. GCP preserves all previous key versions for decryption — secrets encrypted with an old DEK continue to be decryptable because the old KEK version remains available for unwrapping (but not for new encryptions).
To re-encrypt all existing secrets with the current KEK version, use the secret rotation endpoint or enable the automatic re-encryption sweep in your tenant settings. See the Secret Rotation guide for a complete walkthrough.
Security Architecture →
Full threat model, access control design, and compliance roadmap.
Secret Rotation Guide →
Step-by-step walkthrough for rotating secrets and KEKs.