Course outline

21.2

AWS KMS in Depth

Key types and pricing, key policies, rotation, sharing encrypted snapshots and AMIs, multi-Region keys and S3 replication.

30 min Reading + animations

Tip: tap or hover any dotted-underlined term to see what it means.

By the end of this lesson you will be able to

  • Explain what AWS KMS does: it creates, stores and uses encryption keys for you, every use is checked against IAM and the key policy, and every use is logged in CloudTrail.
  • Tell symmetric keys (AES-256, used by every AWS service) from asymmetric keys (RSA and ECC pairs for encryption outside AWS and for digital signatures), and know where HMAC keys fit.
  • Compare AWS owned keys, AWS managed keys and customer managed keys on cost, rotation, policy control and sharing, and know what changes with imported key material.
  • Configure rotation (automatic every 90 to 2,560 days, on demand, or manual with an alias), aliases, grants and safe deletion (7 to 30 days of waiting).
  • Read a key policy, explain the default key policy, and give another account access with both the key policy and that account’s IAM policy.
  • Copy encrypted snapshots across Regions, share encrypted snapshots and AMIs across accounts, and use multi-Region keys and S3 replication of SSE-KMS objects correctly.

#Why KMS: one place for every key

Encryption is only as safe as the key. In lesson 21.1 you saw where data is encrypted: in flight, at rest on the server side, or on the client. Every one of those models needs keys that are created well, stored where nobody can copy them, used only by the right people, rotated, and never lost. Doing that yourself, for hundreds of databases, volumes and buckets, is a full-time job and an easy one to get wrong.

#What KMS is

AWS Key Management Service (KMS) is the AWS service that creates, stores, manages and uses encryption keys for you:

  • AWS runs the hard part. Keys are generated and kept inside KMS’s hardware security modules (HSMs). The key material of a KMS key never leaves them unencrypted; you use a key by calling the KMS API, never by downloading it.
  • Fully integrated with IAM. Every call is authorised by the key’s key policy together with IAM policies, so you decide exactly which roles may encrypt, decrypt or manage each key.
  • Audited. Every use of a key, by you or by an AWS service on your behalf, is recorded in CloudTrail (lesson 19.6): who, which key, which operation, when, from where.
  • Built into most AWS services. EBS, S3, RDS and Aurora, DynamoDB, SSM Parameter Store, Secrets Manager, Lambda, SQS, SNS and many more encrypt with KMS keys at the tick of a box. Anytime a question says “encryption” for an AWS service, KMS is most likely involved.
  • Usable directly. Your own code and the CLI can call Encrypt, Decrypt and GenerateDataKey through the SDK. That lets you keep secrets out of plaintext: a database password or API token in your code or in an environment variable should be stored encrypted and decrypted at run time, never written in clear text (lesson 21.3 shows the managed ways to do this).

#How a KMS key is used

#Direct encryption and the 4 KB limit

The simplest call is Encrypt: you send plaintext and a key ID, KMS returns a ciphertext blob. Decrypt takes the blob back; you do not even name the key, because the blob records which key encrypted it. ReEncrypt moves ciphertext from one key to another inside KMS without ever exposing the plaintext to you.

Encrypt accepts at most 4 KB of plaintext. KMS is made for keys, passwords and small tokens, not for files. For anything bigger, KMS uses envelope encryption, which lesson 21.1 explains in full: GenerateDataKey returns a fresh data key both in plaintext and encrypted under the KMS key; the data is encrypted locally with the plaintext data key, the encrypted data key is stored next to the data, and the plaintext key is thrown away. That is exactly what S3 (SSE-KMS), EBS and RDS do for you behind the scenes.

#The second lock

With KMS encryption, reading data needs two permissions: one on the resource (for example s3:GetObject) and one on the key (kms:Decrypt). The billing team of the hospital may read every object in a bucket by S3 permissions, yet get AccessDenied on patient reports because the key policy does not list them. That second lock, plus the audit trail and the ability to disable a key in one click, is why sensitive data goes under a customer managed key (lesson 10.8 shows the S3 side in detail).

Calls can also carry an encryption context: a set of key-value pairs (S3 uses the object or bucket ARN) that is bound to the ciphertext, must be supplied again to decrypt, appears in CloudTrail, and can be required in key policy conditions.

What happens when you use a KMS key

A Dhaka hospital keeps patient reports in S3 under its own customer managed key. Follow the calls to KMS, the audit trail they leave, and the ways a call can fail.

Scenario

KMS encrypts at most 4 KB itself. Anything bigger is encrypted with a data key: envelope encryption.

Report appIAM role
S3reports bucket
KMSreports-key
CloudTrailaudit log
Encrypt (200 bytes)
Step 1 of 5
1

The app must protect a 200-byte lab API token. It sends the plaintext to KMS with Encrypt. The KMS key itself never leaves KMS’s hardware security modules; the app only ever names it.

#Key types: symmetric, asymmetric, HMAC

#Symmetric keys

A symmetric KMS key is a single AES-256 key that both encrypts and decrypts. It is the default when you create a key, and it is the only kind that AWS services use to encrypt your data at rest (S3, EBS, RDS, DynamoDB and the rest). You never get the key itself: there is no API that exports a symmetric KMS key unencrypted, so every use is a KMS call that is authorised and logged.

#Asymmetric keys

An asymmetric KMS key is a key pair: a public key and a private key, using RSA or elliptic-curve (ECC) algorithms (KMS also offers a Chinese national algorithm in China Regions and newer post-quantum signature keys). Each asymmetric key is created for one usage:

  • Encrypt and decrypt (RSA): anyone with the public key encrypts; only the private key, which never leaves KMS, decrypts.
  • Sign and verify (RSA or ECC): KMS signs with the private key; anyone with the public key verifies the signature. A valid signature proves who signed and that the message was not changed: a digital signature.

The public key can be downloaded (GetPublicKey) and handed to anyone. That is the point: users outside AWS who cannot call the KMS API can still encrypt data for you, or verify your signatures, with ordinary tools. The private key cannot be exported unencrypted.

#HMAC keys

HMAC keys are a third, smaller family: symmetric keys used with GenerateMac and VerifyMac to produce and check a message authentication code, for example to make a tamper-proof token. Like symmetric keys, they never leave KMS. They are a side note for the exam.

Symmetric and asymmetric KMS keys

A Bangladeshi bank works with a payment partner that runs outside AWS and cannot call KMS. Compare one secret key with a key pair whose public half can travel.

Scenario

One AES-256 key does both jobs and never leaves KMS. Only callers with permission can use it.

Partnerno KMS access
Bank appin AWS
KMSkey store
Encrypt / Decrypt
Step 1 of 3
1

A symmetric key is one AES-256 secret that both encrypts and decrypts. This is the default key type, and the only type S3, EBS, RDS and other AWS services use for encryption at rest.

#Who owns the key: three kinds of KMS keys

The notes jump from AWS owned keys straight to customer managed keys. There is a middle tier, and the exam asks about all three.

AWS owned keysAWS managed keysCustomer managed keys
ExamplesSSE-S3, SSE-SQS, DynamoDB’s default encryptionaws/s3, aws/ebs, aws/rds, aws/ssm…Keys you create in KMS, such as alias/reports-key
Created byThe AWS service, in an AWS accountThe AWS service, in your account, when you first use itYou
Visible in your accountNoYes (listed, policy readable)Yes
Monthly key feeNoneNone1 USD per key per month (prorated hourly)
Request chargesNoneYes, per requestYes, per request
Key policyNot yoursFixed by AWS, cannot be editedYours to write
RotationDecided by the owning service, invisible to youAutomatic every year, cannot be changedOptional: automatic (90 to 2,560 days, default 365), on demand, or manual
Disable or deleteNoNoYes
CloudTrail shows each useNoYesYes
Use by another accountNoNoYes, through the key policy

#AWS owned keys

AWS owned keys belong to the AWS service and live in AWS’s own accounts. They protect data in many accounts at once, you never see them, and they are free: no monthly fee, no request charge. S3’s default encryption SSE-S3, SQS’s SSE-SQS and DynamoDB’s default encryption use them. You cannot view, audit, rotate, disable or share them.

#AWS managed keys

AWS managed keys are created in your account by a service the first time you choose “KMS encryption” without naming your own key. Their aliases start with aws/: aws/s3, aws/ebs, aws/rds, aws/lambda. They have no monthly fee, but each request is charged. AWS rotates them every year (since May 2022; before that every three years). You can read their key policy and see their use in CloudTrail, but you cannot edit the policy, rotate them on your own schedule, disable or delete them, and, most importantly for the exam, another account can never use them.

#Customer managed keys

Customer managed keys are the ones you create. You write the key policy, decide who administers and who uses the key, turn on rotation, disable the key in an incident, schedule its deletion, tag it, and give other accounts access. Each costs 1 USD per month plus requests. Choose one whenever a question needs control: a key policy, cross-account sharing, a custom rotation period, the power to disable, or separation of duties.

#Imported key material

Normally KMS generates the key material (origin AWS_KMS). You can instead create a key with no material (origin EXTERNAL) and import your own 256-bit material, generated in your own HSM, to satisfy a rule like “we must generate keys ourselves” or to keep a copy outside AWS. The price is the same 1 USD per month. The differences:

  • No automatic rotation. The slides and the exam say “imported keys can only be rotated manually”: create a new key and repoint the alias. Since 2025 KMS also lets you import new material into the same key and rotate it on demand, but automatic rotation is still not available.
  • You are responsible for the material. You can set an expiration on it, delete it (DeleteImportedKeyMaterial) and re-import it. While the material is missing, the key is unusable.
  • Durability is yours. If you lose your copy and the material is deleted or expires, the data is gone.

For keys held in your own HSMs (a CloudHSM cluster) or entirely outside AWS (an external key store), see lesson 21.5.

#What KMS costs

  • 1 USD per month for each customer managed key, whether generated or imported, single-Region or each multi-Region key. Rotation adds 1 USD per month for the first rotation and again for the second; later rotations are free.
  • Requests: about 0.03 USD per 10,000 symmetric requests in most Regions; asymmetric operations cost more (about 0.15 USD per 10,000 for RSA signing).
  • Free tier: 20,000 requests per month across all Regions (asymmetric operations are excluded).
  • AWS managed keys: no monthly fee, but requests are charged. AWS owned keys: free. A key pending deletion is not billed.

Worked example. The hospital has three customer managed keys (reports, scans, database), rotation on, rotated twice already, and S3 makes 4 million KMS requests a month: 3 × (1 + 2) = 9 USD for keys plus 400 × 0.03 = 12 USD for requests, about 21 USD a month. With S3 Bucket Keys on, the request part drops close to zero (lesson 10.8).

#Rotation

Rotating a KMS key creates new key material while the key ID, ARN, aliases, policy and grants stay the same. KMS keeps every old version of the material and picks the right one to decrypt older ciphertext automatically, so applications and AWS services need no change. Rotation does not re-encrypt existing data and does not rotate the data keys already in use: it protects what is encrypted from now on.

KeyAutomatic rotationOn demandManual
AWS ownedDecided by the serviceNoNo
AWS managedAlways, every yearNoNo
Customer managed, symmetric, KMS-generatedOptional: every 90 to 2,560 days, default 365Yes, up to 25 times per keyYes
Customer managed, imported materialNoYes, after importing new materialYes (the classic answer)
Asymmetric, HMAC, custom key store keysNoNoOnly manual
  • Automatic rotation must be enabled on a customer managed key; the period is set with --rotation-period-in-days.
  • On-demand rotation (rotate-key-on-demand) rotates now, for example after a suspected leak or to prove a runbook works, without changing the automatic schedule.
  • Manual rotation means creating a new key and pointing the alias at it. Applications that use the alias move to the new key; ciphertext created with the old key still names the old key, so keep the old key (do not delete it) for decryption.
  • Each rotation writes a RotateKey event to CloudTrail and an event to EventBridge, which is your proof for auditors.

#Aliases, deletion and grants

  • Aliases are friendly names such as alias/reports-key. One key can have several aliases, each alias points to one key in one Region, and you can repoint an alias to another key (that is manual rotation). Names starting with alias/aws/ are reserved for AWS managed keys.
  • Key states: a key can be Enabled, Disabled (no cryptographic use; re-enable at any time) or Pending deletion. Disabling is the safe emergency switch.
  • Deletion is never immediate. You schedule it with a waiting period of 7 to 30 days (default 30). During the wait the key cannot be used and can be cancelled. After it, the key and its material are gone, and everything encrypted under it becomes unrecoverable. Watch CloudTrail (or a CloudWatch alarm) for attempts to use a key pending deletion: they tell you it is still needed. Only customer managed keys can be deleted.
  • Grants give a principal temporary, narrow permission to use a key without editing the key policy. AWS services create them for you: when EC2 attaches an encrypted EBS volume, it creates a grant so the host can decrypt the volume’s data key. That is why roles that launch encrypted volumes or AMIs in other accounts need kms:CreateGrant.

#Key policies

#Every key has exactly one

A key policy is a resource-based policy attached to a KMS key, written in the same JSON as IAM policies (principal, action, resource, condition). It works like an S3 bucket policy with one big difference: you cannot control access to a KMS key without it. In S3, IAM alone can grant access; in KMS, IAM policies count only if the key policy allows the account to use IAM for that key.

#Default key policy

If you create a key without your own policy, KMS attaches the default key policy. Its core statement gives the account’s root principal full access:

{
  "Sid": "Enable IAM User Permissions",
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::111122223333:root" },
  "Action": "kms:*",
  "Resource": "*"
}

This does not mean only the root user may use the key. It means the whole account is trusted, so IAM policies in that account decide who may use and manage the key. The console version also adds statements for the key administrators and key users you pick.

#Custom key policy

A custom key policy names specific users and roles: who may administer the key (change policy, rotate, disable, schedule deletion) and who may only use it (encrypt, decrypt, generate data keys). That separation of duties is what auditors look for: the admins who manage a key should not be able to read the data, and the app that reads the data should not be able to delete the key. A custom policy is also how you open a key to another account.

#Cross-account access needs two allows

To let account B use a key in account A:

  1. Key policy in account A allows account B (its root principal, or a specific role in it).
  2. IAM policy in account B allows that user or role the KMS actions on the key’s full ARN (aliases from another account do not work).

Both are required. A key policy that trusts account B only lets B’s administrators delegate; a role in B with an IAM policy but no matching key policy statement is denied. The policy evaluation logic is the one in lesson 2.2; SCPs and other organization guard rails from lesson 20.1 can still deny on top.

{
  "Sid": "Allow the client account to use the key",
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::444455556666:root" },
  "Action": ["kms:Decrypt", "kms:DescribeKey", "kms:CreateGrant", "kms:ReEncrypt*", "kms:GenerateDataKey*"],
  "Resource": "*"
}

#KMS keys stay in their Region

A KMS key exists in exactly one Region. A key in Tokyo cannot decrypt anything in Virginia, and a key ARN from Singapore means nothing in Mumbai. So when encrypted data moves to another Region, it must be re-encrypted with a key in the destination Region.

#Copying encrypted snapshots across Regions

An encrypted EBS snapshot or RDS snapshot copied to another Region is decrypted with the source key and re-encrypted with a destination key. AWS does this inside the copy (KMS ReEncrypt); you only name the destination key and need permission on both keys.

  • RDS: you must name a KMS key in the destination Region for an encrypted snapshot copy.
  • EBS: if you do not name one, the copy uses the destination Region’s default EBS key (usually aws/ebs). That works, but a copy under aws/ebs can never be shared with another account later, so name a customer managed key if sharing is planned.
  • Unencrypted snapshots can be encrypted during the copy; encrypted ones cannot be copied unencrypted.

Copying an encrypted snapshot to another Region

A telco copies encrypted database and volume snapshots from Singapore to Mumbai for disaster recovery. KMS keys stay in their own Region, so the copy must be re-encrypted.

Scenario

The source key decrypts in Singapore, the destination key encrypts in Mumbai.

ap-southeast-1
ap-south-1
SnapshotEBS or RDS
Key Acustomer managedSingapore only
Copyin Mumbai
Key BMumbai key
Step 1 of 4
1

The nightly snapshot of the billing database in Singapore is encrypted with Key A, a customer managed key that exists only in ap-southeast-1. Every KMS key belongs to exactly one Region.

#Sharing encrypted snapshots with another account

The steps, matching the notes and the slides:

  1. 1. Encrypt with a customer managed key

    The snapshot must be encrypted with a customer managed key of your account. If it is encrypted with the AWS managed key (aws/ebs, aws/rds), you cannot share it: that key’s policy only trusts your account and cannot be edited. First copy the snapshot and re-encrypt it with a customer managed key, then share the copy.

  2. 2. Open the key policy to the target account

    Add a key policy statement that allows the target account (kms:DescribeKey, kms:CreateGrant, kms:Decrypt, kms:ReEncrypt*, kms:GenerateDataKey*).

  3. 3. Share the snapshot

    EBS: modify-snapshot-attribute with the target account ID. RDS: modify-db-snapshot-attribute with the restore attribute. Encrypted snapshots can be shared with accounts, never made public.

  4. 4. In the target: copy and re-encrypt

    The target account, whose IAM policy also allows the source key, copies the shared snapshot and encrypts the copy with its own customer managed key. Its copy no longer depends on your key.

  5. 5. In the target: create a volume or restore

    The target creates an EBS volume, or restores the RDS instance, from its own copy.

Lesson 5.2 and lesson 7.4 give the EBS and RDS side; here the focus is the key.

#Sharing an encrypted AMI

An AMI with encrypted EBS snapshots follows the same logic (lesson 4.3 covers AMI sharing in general):

  1. The AMI’s snapshots are encrypted with a customer managed key of the source account (not aws/ebs; copy the AMI with a customer managed key first if needed).
  2. Modify the image attribute to add a launch permission for the target account.
  3. Share the KMS key used by the AMI’s snapshots with the target account (key policy).
  4. The IAM role or user in the target account needs kms:DescribeKey, kms:ReEncrypt*, kms:CreateGrant and kms:Decrypt on that key.
  5. When launching, the target can name a new KMS key in its own account to re-encrypt the volumes, or copy the AMI with its own key first, so it no longer depends on the source key.

Sharing an encrypted snapshot or AMI with another account

A Sylhet software house hands a client an encrypted database snapshot and a golden AMI. Watch which key works, which permission is missing, and how the client ends up owning its copy.

Scenario

Customer managed key, key policy, share, copy with the client’s key, create a volume.

Vendor 111122223333
Client 444455556666
Snapshot / AMIencrypted
vendor-keycustomer managed
Client copy
EC2
Client roleIAM policy
client-keyclient’s own
Step 1 of 5
1

Step 1: the snapshot is encrypted with vendor-key, a customer managed key. Only a key whose policy you can edit can be opened to another account.

Now try the chain yourself: pick what is shared, the key and the settings, and see which step blocks.

Can this be shared with the other account?

Describe what the vendor did, then press Check. Try the aws/ebs snapshot first, then a customer managed key with only the key policy set, then everything set.

What is being shared?

Encrypted with

Press Check to walk the chain.

#Multi-Region keys

A multi-Region key (MRK in AWS diagrams) is a set of KMS keys in different Regions that are interchangeable: a primary key and its replica keys share the same key ID (it starts with mrk-), the same key material, the same key spec and the same rotation. Data encrypted in one Region can be decrypted in another with no re-encryption and no cross-Region call to KMS.

arn:aws:kms:ap-southeast-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab   primary
arn:aws:kms:ap-south-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab       replica
arn:aws:kms:eu-west-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab        replica

What to remember:

  • Not global. A multi-Region key exists only in the Regions you replicate it to (primary plus replicas), not everywhere.
  • Each key is managed independently. Every replica is its own KMS resource with its own key policy, grants, aliases, tags and enabled state, billed 1 USD per month each. Only the material, key ID, key spec and rotation are shared; rotation is turned on, and on-demand rotation is started, at the primary.
  • Choose at creation. An existing single-Region key cannot be converted. If the primary’s Region is lost for long, you can promote a replica to primary.
  • Use only when needed. AWS recommends single-Region keys by default: one key in many Regions widens the impact of a mistake. Multi-Region keys are for client-side encryption that must be decrypted in several Regions, global applications that sign or verify in many Regions, and disaster recovery that must decrypt without the primary Region.

#DynamoDB global tables with client-side encryption

DynamoDB global tables are already multi-Region, and DynamoDB already encrypts data at rest on the server side (lesson 15.5). But some fields, such as an NID number, a card number or a medical code, must be protected even from people and tools that can read the table. So the app encrypts those attributes client-side with the AWS Database Encryption SDK (formerly the DynamoDB Encryption Client) before writing them. The global table replicates the ciphertext. Now the app in the other Region must decrypt:

  • With a single-Region key, the app in Mumbai has to call KMS in Singapore for every read: added latency, cross-Region traffic, and no decryption at all if Singapore is down.
  • With a multi-Region key replicated in each table Region, every app decrypts with the replica key in its own Region: low latency, and it keeps working when another Region fails.

#Aurora Global Database

The same reasoning applies to an Aurora Global Database (lesson 7.3). If you encrypt sensitive columns with the AWS Encryption SDK before they reach the database, applications in the secondary Regions need the key locally: a multi-Region key. A bonus of client-side column encryption: even database administrators see only ciphertext.

Multi-Region keys with a global database

A mobile wallet encrypts customers’ NID numbers client-side before writing them to a DynamoDB global table in Singapore and Mumbai. Which key lets the Mumbai app read them?

Scenario

Primary and replica share the key ID and key material, so each Region decrypts locally.

ap-southeast-1
ap-south-1
Wallet app
Primary keymrk-1234…primary
Global table
Wallet app
Replica table
Replica keymrk-1234…replica
Step 1 of 4
1

The team created a multi-Region primary key in Singapore and replicated it to Mumbai. Both have the same key ID (mrk-…) and the same key material, but each is a separate resource in its own Region.

#S3 replication of encrypted objects

Replication (lesson 10.4) handles encrypted objects differently depending on the key:

Object encryptionReplicated by default?
None, or SSE-S3Yes
SSE-C (customer-provided key)Yes
SSE-KMS or DSSE-KMSNo: you must opt in

To replicate SSE-KMS objects:

  1. Enable the option in the replication rule to replicate objects encrypted with KMS keys.
  2. Name the KMS key that encrypts the replicas in the destination Region (the source key cannot be used there), and make sure that key’s key policy allows the replication role.
  3. Give the replication IAM role kms:Decrypt on the source key and kms:Encrypt on the destination key.
  4. Expect KMS load: every object is one decrypt in the source Region and one encrypt in the destination Region. At high rates KMS may throttle; enable S3 Bucket Keys and request a Service Quotas increase if needed.

Multi-Region keys can be used for source and destination, but S3 currently treats them as independent keys: the object is still decrypted and re-encrypted.

Replicating SSE-KMS objects between Regions

An online shop replicates order invoices from Singapore to Mumbai. Plain and SSE-S3 objects copy at once; SSE-KMS objects need an opt-in, a destination key and KMS rights on the role.

Scenario

Unencrypted and SSE-S3 objects replicate by default; SSE-C objects too.

ap-southeast-1
ap-south-1
Source bucket
Key ASingapore
Replication role
Target bucket
Key BMumbai
Step 1 of 2
1

A CRR rule is set up with a replication role. An invoice encrypted with SSE-S3 is uploaded in Singapore.

#What goes wrong

  • AccessDenied on an object you can read in S3: the caller lacks kms:Decrypt on the object’s key (key policy or IAM). Multipart uploads also need kms:Decrypt.
  • Cross-account call denied although the key policy allows the account: the role in the other account has no IAM permission on the key’s full ARN, or it used an alias.
  • Cannot share a snapshot or AMI: it is encrypted with aws/ebs or aws/rds. Copy it with a customer managed key first.
  • Snapshot copy to another Region fails: the named key is from the source Region, or the caller lacks kms:Decrypt on the source key or kms:Encrypt/kms:CreateGrant on the destination key.
  • An EC2 launch from a shared AMI fails or the instance stops at once: the target role lacks kms:CreateGrant or kms:Decrypt on the AMI’s key.
  • New SSE-KMS objects do not replicate: the opt-in is off or the role lacks KMS permissions.
  • Everything encrypted with a key is suddenly unreadable: the key was disabled, or scheduled for deletion. Re-enable, or cancel the deletion within the waiting period.
  • Data lost for good: a key was deleted after its waiting period, or imported key material was deleted with no copy kept.
  • Throttling errors at peak load: the shared KMS request quota is reached. Bucket Keys, data key caching, quota increase.
  • Apps in a second Region cannot decrypt client-side encrypted data: the data was encrypted with a single-Region key. Use a multi-Region key.
  • Old data does not decrypt after “rotating” by creating a new key: the old key was deleted. With manual rotation, keep the old key enabled.

#KMS in system design

  • One customer managed key per data domain and environment (for example prod-patient-records, prod-payments, dev-shared), not one key for everything: a narrow key policy limits who can read what, and disabling one key in an incident does not stop the whole company.
  • Separation of duties: key administrators (security team) are not key users (applications); applications get only kms:Decrypt and kms:GenerateDataKey on the keys they need.
  • Multi-account setups: a central security account owns shared keys and grants workload accounts access through key policies; backup and DR accounts get copies re-encrypted with their own keys, so a compromise of one account does not expose the backups.
  • DR across Regions: copy snapshots with destination-Region keys; use multi-Region keys only where client-side encrypted data must be read in several Regions.
  • Cost and scale: turn on S3 Bucket Keys, cache data keys where the SDK supports it, and keep the free AWS owned keys for data that needs no key control.
  • Audit: CloudTrail on all Regions, alarms on DisableKey and ScheduleKeyDeletion, and AWS Config rules (lesson 19.7) to check that rotation is enabled on customer managed keys.

#Try it yourself

These commands use the AWS CLI v2. Customer managed keys cost 1 USD per month, so schedule deletion of the test keys at the end.

# 1. Create a symmetric customer managed key and an alias
aws kms create-key --description "Hospital reports key" --region ap-southeast-1
# { "KeyMetadata": { "KeyId": "1234abcd-12ab-34cd-56ef-1234567890ab",
#   "KeySpec": "SYMMETRIC_DEFAULT", "KeyUsage": "ENCRYPT_DECRYPT", "Origin": "AWS_KMS",
#   "KeyManager": "CUSTOMER", "KeyState": "Enabled", "MultiRegion": false } }
aws kms create-alias --alias-name alias/reports-key --target-key-id 1234abcd-12ab-34cd-56ef-1234567890ab

# 2. Encrypt and decrypt a small secret (at most 4 KB)
aws kms encrypt --key-id alias/reports-key --plaintext fileb://lab-token.txt \
  --query CiphertextBlob --output text | base64 --decode > lab-token.enc
aws kms decrypt --ciphertext-blob fileb://lab-token.enc --query Plaintext --output text | base64 --decode

# 3. Envelope encryption: a data key for a big file
aws kms generate-data-key --key-id alias/reports-key --key-spec AES_256
# { "CiphertextBlob": "AQIDAHh...", "Plaintext": "kJ8x...", "KeyId": "arn:aws:kms:ap-southeast-1:111122223333:key/1234abcd-..." }

# 4. Rotation: every 180 days, plus one rotation now
aws kms enable-key-rotation --key-id 1234abcd-12ab-34cd-56ef-1234567890ab --rotation-period-in-days 180
aws kms rotate-key-on-demand --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
aws kms get-key-rotation-status --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
# { "KeyRotationEnabled": true, "RotationPeriodInDays": 180, "NextRotationDate": "2027-04-30T..." }

# 5. Open the key to another account (edit key-policy.json first) and give an app a grant
aws kms put-key-policy --key-id 1234abcd-12ab-34cd-56ef-1234567890ab --policy-name default --policy file://key-policy.json
aws kms create-grant --key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
  --grantee-principal arn:aws:iam::111122223333:role/report-app --operations Decrypt GenerateDataKey

# 6. Copy an encrypted EBS snapshot to Mumbai with a Mumbai key
aws ec2 copy-snapshot --region ap-south-1 --source-region ap-southeast-1 \
  --source-snapshot-id snap-0123456789abcdef0 --encrypted \
  --kms-key-id arn:aws:kms:ap-south-1:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321

# 7. Share a snapshot and an AMI with the client account
aws ec2 modify-snapshot-attribute --snapshot-id snap-0123456789abcdef0 \
  --attribute createVolumePermission --operation-type add --user-ids 444455556666
aws ec2 modify-image-attribute --image-id ami-0abcdef1234567890 \
  --launch-permission "Add=[{UserId=444455556666}]"

# 8. A multi-Region key and its replica in Mumbai
aws kms create-key --multi-region --description "Wallet NID key" --region ap-southeast-1
# "KeyId": "mrk-1234abcd12ab34cd56ef1234567890ab", "MultiRegion": true
aws kms replicate-key --key-id mrk-1234abcd12ab34cd56ef1234567890ab --replica-region ap-south-1

# 9. Clean up: schedule deletion with the shortest wait (and cancel if it is still needed)
aws kms schedule-key-deletion --key-id 1234abcd-12ab-34cd-56ef-1234567890ab --pending-window-in-days 7
# { "KeyState": "PendingDeletion", "DeletionDate": "2026-11-08T...", "PendingWindowInDays": 7 }
aws kms cancel-key-deletion --key-id 1234abcd-12ab-34cd-56ef-1234567890ab

Then open CloudTrail’s event history, filter by event source kms.amazonaws.com, and find your Encrypt, Decrypt, GenerateDataKey and RotateKey events with your role as the caller.

#Summary

Key takeaways

  • KMS creates, stores and uses keys for you; keys never leave it unencrypted; every use is authorised by the key policy + IAM and logged in CloudTrail. Exam words: “auditable”, “centralized key management”. CMK is the old name for a KMS key.
  • Encrypt takes at most 4 KB; bigger data uses data keys (envelope encryption). Reading KMS-encrypted data needs permission on the resource and on the key.
  • Symmetric (AES-256): what every AWS service uses. Asymmetric (RSA, ECC): encrypt/decrypt or sign/verify, public key downloadable for users outside AWS who cannot call KMS, digital signatures. HMAC keys for message authentication codes.
  • AWS owned (free, invisible: SSE-S3, SSE-SQS, DynamoDB default) → AWS managed (aws/s3, aws/ebs, aws/rds: no monthly fee, pay per request, rotated yearly, policy fixed, not shareable) → customer managed (1 USD per month + requests, your policy, optional rotation 90–2,560 days, default 365, on demand up to 25 times, shareable, deletable). Imported material: no automatic rotation, manual rotation with an alias.
  • Deletion waits 7–30 days (default 30); disabling is the reversible emergency switch. Aliases name keys; grants give services temporary use.
  • Default key policy trusts the account, so IAM decides. Cross-account = key policy and the other account’s IAM policy.
  • Keys are Regional: cross-Region snapshot copies are re-encrypted with a destination key. Sharing snapshots or AMIs across accounts needs a customer managed key, key policy access, the share or launch permission, IAM rights in the target, and ideally a re-encrypted copy in the target.
  • Multi-Region keys: same key ID and material in chosen Regions, not global, each managed independently; for DynamoDB global tables / Aurora Global Database with client-side encryption.
  • S3 replication: SSE-S3 and SSE-C replicate by default; SSE-KMS needs the opt-in, a destination key, and kms:Decrypt + kms:Encrypt on the role; watch the KMS quota and use Bucket Keys.