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)
"sk-proj-abc123..." — 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 GCP KMS (FIPS 140-2 Level 3 HSM). Never exported. Never touches our servers.
The key insight: the KEK never leaves the HSM. GCP KMS performs wrap/unwrap operations inside the hardware boundary. 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: HSM (FIPS 140-2 Level 3)
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.
FIPS 140-2 Level 3 HSM
GCP KMS HSM uses Hardware Security Modules certified to FIPS 140-2 Level 3. This standard requires:
Tamper evidence
Physical seals that break on unauthorized access; keys are erased if tampering is detected.
Identity-based auth
Operators must authenticate to the HSM before performing key operations.
Key export prevention
Private key material cannot be exported from the HSM boundary — ever.
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 GCP KMS CryptoKey.Decrypt(wrapped_DEK)
- 5KMS returns plaintext DEK (inside HSM 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 useless to 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.