Data has three states, and each has its own attacker.
In transit: a sniffer on the path. At rest: whoever gets a copy. In use: whoever owns the app server, which reads plaintext.
Each layer decrypts at a different point.
Disk encryption stops a stolen drive. TDE adds leaked backups. Field-level adds DBAs and SQL injection. Only end-to-end survives a compromised app server.
Random 96-bit GCM nonces, one key, 20,000 encryptions a second.
The limit
NIST caps one key at 2³² encryptions. At that rate you hit it in about 2.5 days. Use many keys.
Envelope encryption: the KMS only ever sees a small key.
Encrypt the claim PDF locally with a fresh data key. The KMS wraps that key under the tenant’s KEK; store the wrapped key beside the ciphertext.
67/s
KMS calls, down from 12,000
A data key per record means 12,000 Decrypt calls a second, over the 10,000 default. One key per tenant per day, cached 5 minutes in 40 pods, needs 67.
Does key rotation re-encrypt all your data?
Bad: Rotate means re-encrypt
Rewrite every object, replica and backup.
Good: Rotate means new version
New wraps use v2; v1 only decrypts. Re-wrapping 200M DEKs takes ≈ 11 hours.
Destroy one tenant’s key, and every backup becomes noise.
Erasing a tenant from 35 snapshots, a replica and a data-lake export is hard. Destroy its KEK, and every copy becomes unreadable.
Find a row by an encrypted ID
- Randomised AEAD: no queries, leaks only length
- Blind index: an HMAC column for equality
- Tokenize card numbers; only the vault maps back
- Never deterministic on low-entropy columns
Remember
TLS in transit; pick the at-rest layer by attacker. AEAD with unique nonces, data keys wrapped by a per-tenant KEK in a KMS, rotation by version, and crypto-shredding to delete.