Skip to content
cryptographyintermediate#kms#encryption#cloud-security#hsm#key-management

Cloud Key Management: KMS, Envelope Encryption, HSMs

How cloud KMS works: envelope encryption with data keys and key-encryption keys, key policies and separation of duties, rotation, BYOK and external key stores, and what encryption at rest actually protects against.

Encryption is the easy part. AES-256 is not going to be broken by anyone attacking your object storage, and every cloud service will encrypt at rest with one checkbox.

The hard part is the key: where it lives, who can use it, how its use is recorded, what happens when it rotates, and what an attacker who compromises an application can do with it. Key management is where the security of encrypted data actually resides, and a correctly encrypted system with a key any compromised process can use is protecting against a narrow set of threats.

This guide covers how a cloud KMS works, the envelope pattern everything is built on, the controls that matter, and an honest statement of what encryption at rest defends against.

Scope: Encryption Explained owns the algorithms, Symmetric vs Asymmetric Encryption owns the primitive types, and Cloud Misconfigurations owns the settings around them. This page owns key management.

Envelope encryption

The pattern underneath every cloud encryption feature.

  1. Your application asks the KMS to generate a data key. The KMS returns it twice: once in plaintext, once encrypted under a key-encryption key that never leaves the service.
  2. The application encrypts the data locally with the plaintext data key, then discards that plaintext from memory.
  3. The wrapped data key is stored alongside the ciphertext.
  4. To read the data, the application sends the wrapped key to the KMS, which decrypts it if policy allows, and returns the plaintext data key for local decryption.
# Generate a data key: plaintext for local use, ciphertext to store
aws kms generate-data-key --key-id alias/app-data --key-spec AES_256 \
  --encryption-context tenant=acme,purpose=documents
 
# Later, unwrap it. The same context must be supplied or the call fails.
aws kms decrypt --ciphertext-blob fileb://wrapped.key \
  --encryption-context tenant=acme,purpose=documents

Two reasons this design is universal. The KMS accepts only small payloads directly, on the order of a few kilobytes, so bulk encryption has to happen locally. And keeping the root key inside hardware that never releases it is what makes the hierarchy meaningful: the most sensitive material in the system is never present in your application's memory at all.

Encryption context is the parameter most teams skip and should not. It is additional authenticated data bound to the wrapped key: the decrypt call must supply the same context or it fails. That does two things. It prevents a data key wrapped for one tenant from being unwrapped in a request that claims a different tenant, which turns a category of application logic bug into a hard failure. And the context appears in the audit log, so the record shows what was decrypted rather than only that something was.

Provider-managed and customer-managed keys

Provider-managedCustomer-managed
Who creates itThe serviceYou
Policy controlNoneFull key policy
Rotation controlProvider's scheduleYours, or automatic
Per-use audit trailLimitedEvery operation logged
Can be disabled or deletedNoYes, with a waiting period
CostFree or negligiblePer key, plus per request

Provider-managed keys are a reasonable default for data with no specific requirement. Move to a customer-managed key when you need any of: a policy restricting which principals can decrypt, an audit trail of every use, control over rotation, the ability to revoke access by disabling the key, or per-tenant separation for crypto-shredding.

The mistake worth avoiding is creating one customer-managed key per service out of habit. Keys have a per-request cost and an administrative burden, and a key that protects everything gives you no ability to revoke anything selectively. Group keys by blast radius: what would you want to be able to disable independently.

Key policy and separation of duties

This is where the real access control lives, and it is a different document from your identity policies.

A key policy is a resource policy on the key itself. Access to use a key is the intersection of what the key policy allows and what the caller's identity policy allows, which means an administrator with broad IAM permissions still cannot use a key whose policy does not name them.

That property is what makes separation of duties enforceable:

  • Key administrators can create, rotate, set policy on and schedule deletion of keys, and cannot use them to decrypt data.
  • Data users can call decrypt through the key policy, and cannot change the policy that permits it.

An estate where the same role does both has separation of duties on an org chart rather than in the system. Splitting them means that compromising a data-plane role yields decryption of what that role could already read, and compromising an administrative role does not yield plaintext.

Two more controls worth applying:

  • Condition keys on the policy. Restricting decrypt to calls carrying a specific encryption context, or coming through a specific service, narrows what a stolen credential can do.
  • Grants for temporary, scoped access, rather than widening a policy for a one-off job and never narrowing it again.

Rotation, revocation and deletion

Rotation generates new key material and uses it for new encryptions while retaining previous versions for decrypting existing data. Automatic annual rotation is the common default. The practical effect is bounding how much data any single piece of key material protects; it does not retroactively re-protect old ciphertext. Re-encrypting historical data under new material is a separate campaign that most organisations do only when they have reason to believe old material was exposed.

Disabling a key is the fast revocation. Every decrypt operation against it fails immediately, which makes it the emergency brake during an incident, and which makes every service using that key stop working. Know in advance which services those are.

Deletion is scheduled rather than immediate, with a mandatory waiting period, precisely because deleting a key destroys the data it protects with no recovery. During the waiting period the key can be restored. Treat the schedule-deletion call as a high-severity alert in every environment.

BYOK, HSMs and external key stores

Regulatory and contractual requirements sometimes dictate who may possess key material, and the cloud offerings step through several levels:

Standard KMS. Provider generates and holds key material in hardware security modules under their control. Validated to FIPS 140 at the level the provider publishes.

Dedicated or managed HSM. A single-tenant HSM cluster you control, typically validated to a higher level, with the provider unable to access the key material. More administrative work and more availability responsibility.

Imported key material (BYOK). You generate the material and import it. The provider stores and uses it; you keep the original. This satisfies requirements about origin, and it makes you responsible for having a copy if the imported material expires or is deleted.

External key store. Key material stays entirely outside the provider, in your own key manager, and the cloud service calls out to it for every cryptographic operation. This is the strongest separation available and it comes with the strongest availability coupling: when your key manager or the link to it is unavailable, the cloud data is unreadable. Model that failure before choosing it, because a key manager outage becomes a full outage of everything it protects.

What encryption at rest actually protects

Being precise here is the most useful thing in this guide, because encryption at rest is frequently deployed against threats it does not address.

It defends against paths that bypass the application:

  • A physical disk stolen or improperly decommissioned.
  • A storage snapshot shared with the wrong account, which is one of the settings in Cloud Misconfigurations.
  • An object storage bucket exposed publicly, where the objects are ciphertext.
  • Backup media lost in transit.
  • A provider employee with infrastructure access and no key access.

It does not defend against:

  • A compromised application or instance role that holds decrypt permission. It asks correctly, gets plaintext, and the KMS logs a successful authorised call.
  • A stolen credential with the same permission.
  • SQL injection or an application logic flaw, since the application decrypts as part of its normal function.
  • An insider with legitimate access to the data.

That asymmetry is why key policy, least privilege and decrypt-volume monitoring do more for real risk than choosing a stronger cipher. The most common cloud data loss is an authorised principal being used by the wrong person, and only the access controls around the key touch that.

Monitoring

Every KMS operation is logged, and those logs answer questions no other source can.

Detections worth having:

  • Decrypt volume anomalies. A principal that normally unwraps a handful of data keys an hour asking for thousands is bulk data access in progress. This is often the earliest available signal of exfiltration, because it happens at the moment of reading rather than at the moment of transfer.
  • Decrypt from an unexpected principal, region or network.
  • Any change to a key policy. Rare, deliberate, and worth reviewing every time.
  • ScheduleKeyDeletion or key disable. Either an authorised change you know about or a serious incident.
  • Failed decrypt attempts, particularly failures caused by a mismatched encryption context, which indicate either a bug or an attempt to unwrap data for the wrong tenant.

Design patterns worth knowing

Per-tenant keys for crypto-shredding. A multi-tenant system with one key per tenant can honour a deletion requirement by destroying the key, which renders that tenant's data unreadable in every copy including immutable backups. This is the practical answer to the tension between deletion obligations and the immutable backups described in 3-2-1 Backup Strategy. It works only if the key was genuinely used for one tenant.

Separate keys per environment and per data class, so that revoking or investigating one does not stop everything.

Client-side encryption for the highest-sensitivity fields, where the data is encrypted before it reaches the cloud service at all, so the service never holds plaintext. Higher operational cost, and the right answer for a small number of fields rather than for everything.

Keys and backups kept independent. The key needed to restore a backup must not live only inside the environment being restored.

The verdict

Cloud key management is mostly an access control problem wearing cryptographic clothes. The algorithms are settled and the envelope pattern is standard; what varies between a strong deployment and a weak one is who can call decrypt, whether that is separated from who administers the key, whether the context binds the operation to something meaningful, and whether anyone watches the decrypt volume.

Set the honest expectation with it. Encryption at rest closes the storage-layer paths, which are real and have caused real breaches. It does not close the path where an attacker becomes a principal your policy trusts, and that path is the one most cloud incidents take.

Sources & further reading