Guide

Sending a 50 GB database dump to a key service to encrypt would be slow and expensive. Envelope encryption avoids that. A random data key encrypts the data locally. A master key, held inside a key service (KMS), encrypts the small data key. The master key never leaves KMS.

Concept

Before you start. A data key is a symmetric key: the same key encrypts and decrypts. For that basic idea, read crypto basics.

Walking through it

  1. Generate a random data key (DEK) locally. A 256-bit AES key is 32 bytes.
  2. Encrypt the payload with the data key. This is fast and runs on your machine.
  3. Ask KMS, or Vault Transit, to encrypt the data key with the master key (CMK).
  4. Store the ciphertext together with the encrypted data key. Drop the plaintext data key from memory.
  5. To decrypt, ask KMS to unwrap the data key. KMS checks IAM first. Then decrypt the payload locally.

The payload is 50 GB, but KMS only handles 32 bytes. That is why the pattern is fast.

Example

S3 server-side encryption with KMS (SSE-KMS) works this way. Each object gets its own data key, and the CMK never leaves KMS. When you rotate the CMK, new objects use the new key material. Old objects still decrypt until you re-encrypt them.

Key hierarchy

Design the keys as carefully as the data:

  • Use one CMK per environment or data class, such as prod-pii and prod-app.
  • Keep key administration in a different account from key use.
  • Log every decrypt.
  • Grant kms:Decrypt only to roles that must read that data class.

A stolen app role that can decrypt everything is almost as bad as plaintext data.

Transit encryption versus a secret store

Vault Transit and cloud KMS also offer encryption as a service. The app sends data and gets ciphertext back, and never sees the master key. Use that for application fields, such as an SSN stored in your database.

Use a secret store for passwords that your app needs to connect to Postgres or Stripe. Do not put every ciphertext into a secrets manager. It has version limits and API rate limits that will hurt you.

Common mistakes

  • Letting one role decrypt every class of data. Scope permissions by data class.
  • Sending large payloads straight to KMS. Use a local data key.
  • Storing application ciphertext in a secret store. Use Transit or KMS for that.

Check yourself

  1. Why does envelope encryption wrap a small data key instead of the payload? Answer: wrapping a 32-byte key is fast and cheap. Sending the whole payload through KMS would be slow and costly.
  2. A role can call kms:Decrypt on every key. What is the risk? Answer: a stolen role can read every class of data, which is almost as bad as plaintext.

Key takeaways

  • A local data key encrypts the data. A master key in KMS wraps the data key.
  • Master keys never leave KMS.
  • Scope decrypt permissions by data class, and log every decrypt.
  • Next, rotation explains how to replace keys and secrets without an outage.

Further learning

AWS's KMS concepts page is the clearest explanation of CMKs, data keys and envelope encryption.

AWS KMS conceptsThe KMS keys that you create and manage for use in your own cryptographic applications are of a type known as customer managed keys . Customer managed keys can also be used in conjunction with AWS services that use KM…docs.aws.amazon.com