KMS & envelope encryption
CMK/CMEK, key policies, grants, and data-at-rest patterns.
Cloud KMS is not a vault you push plaintext into and pull it back out of — that would not scale and would move every byte through the service. It is a manager of small, wrapping keys. The pattern that makes it work at any data size is envelope encryption, and understanding it changes how you think about rotation, revocation, and who can actually read your data.
Envelope encryption, concretely
You ask KMS for a data key. It returns two forms of the same key: a plaintext copy you use immediately to encrypt your data locally, and a ciphertext copy that only KMS can unwrap. You encrypt the payload with the plaintext data key, then throw the plaintext key away and store the wrapped data key next to the ciphertext. To decrypt later, you send the wrapped key back to KMS, which unwraps it (if your identity is allowed), and you decrypt locally. The bulk data never touches KMS; only tiny keys do.
# 1. Get a data key: plaintext (to use now) + ciphertext (to store).aws kms generate-data-key --key-id alias/app-data --key-spec AES_256 \--query '{p:Plaintext,c:CiphertextBlob}' --output json > dk.json# 2. Encrypt the payload locally with the plaintext key, then DISCARD it.openssl enc -aes-256-cbc -in report.csv -out report.enc -K "$(jq -r .p dk.json | base64 -d | xxd -p -c256)"# store report.enc + the CiphertextBlob (dk.json .c) together; delete plaintext.# 3. To read: send the wrapped key back; KMS unwraps only if you're allowed.aws kms decrypt --ciphertext-blob fileb://wrapped.key \--query Plaintext --output text | base64 -d # -> plaintext data key, locally
The key policy is the real access control
Reading the ciphertext store is not enough to read the data — the attacker also needs permission to call kms:Decrypt on the key. That decoupling is the point: an S3 bucket reader who cannot use the key sees only ciphertext. Because the key policy governs use, disabling a customer-managed key instantly renders all data it protects unreadable, giving you a genuine kill switch a provider-default key cannot. And because only the wrapping key is versioned, rotating the KMS master needs no re-encryption of the data itself.