☰ All modules Tier 1 · Security and encryption (KMS, Secrets Manager, Parameter Store) GuideCheat sheet ‹ dynamodbadvanced-identity ›
Contents
  1. How Security and encryption (KMS, Secrets Manager, Parameter Store) appears on DVA-C02
  2. 1. Encryption models and KMS key types
  3. 2. Key policies grants and cross account access
  4. 3. KMS API operations and the 4 KB limit
  5. 4. Envelope encryption and the Encryption SDK
  6. 5. Request quotas throttling and S3 Bucket Keys
  7. 6. Key rotation deletion and multi Region keys
  8. 7. CloudHSM versus KMS and custom key stores
  9. 8. SSM Parameter Store
  10. 9. Secrets Manager basics and Parameter Store comparison
  11. 10. Secrets Manager rotation and replication
  12. 11. CloudFormation dynamic references and RDS managed secrets
  13. 12. CloudWatch Logs encryption and CodeBuild secrets
  14. 13. Nitro Enclaves and attested KMS requests
  15. Quick decision rules
  16. Changed vs older material

Security and encryption (KMS, Secrets Manager, Parameter Store) — DVA-C02 Mastery Guide

  • Sources: course chapter 23 (Security and Encryption: KMS, Encryption SDK, SSM Parameter Store, Secrets Manager, CloudHSM, CloudFormation dynamic references, CloudWatch Logs and CodeBuild secrets, Nitro Enclaves). The course serves as the syllabus only; all wording here is original.
  • Written 2026-10-12 · values checked against AWS docs on 2026-10-12. The marker ⚠️ Changed: <current>. Older material may say <old>. flags a value or behaviour that differs from the course or from older practice tests: learn the current value. ⚠️ unverified marks a detail that could not be confirmed in AWS documentation: don't build an exam answer on it. Every change is listed in Changed vs older material; once you confirm them they go to notes/current-facts.md.
  • Tier 1 (highest exam weight), bank target 40 questions. Domain: Security (26 % of the exam), task statements "encryption with AWS services" and "sensitive data in application code". KMS throttling, caching and rotation failures also appear as troubleshooting scenarios.
  • How to use it: /explain <topic> teaches from these sections (concept → exam facts → developer angle → traps → 3 check questions); /quiz security-encryption asks bank questions whose source_note links point at the ## N. headings below; /drill security-encryption fires short recall prompts from notes/security-encryption-cheat-sheet.md. Suggested loop: read a section and answer its practice questions before opening the answers → /explain what is still unclear → /quiz → /drill.

How Security and encryption (KMS, Secrets Manager, Parameter Store) appears on DVA-C02

The exam treats encryption as something your code and configuration must get right, not as cryptography theory:

Typical question shapes: a scenario with one deciding constraint (LEAST operational overhead, MOST secure, most cost-effective, no application code changes); an error code to explain; "Which TWO actions…" with five options; the exact API action, CLI flag, condition key or template syntax that does the job.

Domain map: Security → every section · Troubleshooting and Optimization → §3 (errors), §5 (quotas, Bucket Keys), §9–§10 (caching, rotation failures) · Development with AWS Services → §4 (Encryption SDK), §8–§9 (reading configuration and secrets) · Deployment → §11 (templates), §12 (CodeBuild).

Out of scope here: S3 encryption types and headers beyond Bucket Keys (see notes/s3-guide.md), EBS volume, snapshot and AMI encryption workflows (see notes/ec2-mastery-guide.md §6), IAM policy grammar and policy evaluation (see notes/iam-guide.md and notes/advanced-identity-guide.md), TLS certificates with ACM (see notes/other-services-guide.md), RDS encryption at rest and IAM database authentication (see notes/rds-guide.md), Lambda environment-variable encryption (see notes/lambda-guide.md), ECS secret injection (see notes/containers-guide.md), buildspec phases and artifacts (see notes/cicd-guide.md), CloudFormation template mechanics (see notes/cloudformation-guide.md). No HSM administration or network design: VPC endpoints and NAT gateways appear only as the reason a call times out.

# Topic Why it is on the exam
1 Encryption models and KMS key types Who controls the key decides auditing, sharing and cost; asymmetric vs symmetric vs HMAC
2 Key policies grants and cross account access Most "access denied" questions are key policy questions
3 KMS API operations and the 4 KB limit The right API for the job and the error codes that come back
4 Envelope encryption and the Encryption SDK Anything bigger than 4 KB; data key caching under load
5 Request quotas throttling and S3 Bucket Keys ThrottlingException fixes, SSE-KMS cost
6 Key rotation deletion and multi Region keys Rotation types and periods, safe deletion, cross-Region decryption
7 CloudHSM versus KMS and custom key stores When a single-tenant HSM is required
8 SSM Parameter Store Tiers, hierarchies, SecureString, policies, throughput
9 Secrets Manager basics and Parameter Store comparison Choosing the store; retrieving and caching secrets; cross-account
10 Secrets Manager rotation and replication Rotation steps, schedules, strategies, failures; multi-Region secrets
11 CloudFormation dynamic references and RDS managed secrets Secrets in templates without exposing them
12 CloudWatch Logs encryption and CodeBuild secrets KMS keys on log groups; secrets in builds
13 Nitro Enclaves and attested KMS requests Processing data that even the host must not see

1. Encryption models and KMS key types

Concept

Exam facts

Customer managed key AWS managed key AWS owned key
Created by You (CreateKey) An AWS service, in your account (aws/s3, aws/ebs, aws/ssm, aws/secretsmanager, …) An AWS service, in its own account
Key policy Written by you Set by the service; viewable, not editable Not visible
Use from your own code Yes No, only through the owning service No
Share with another account Yes (key policy + IAM) No Decided by the service
CloudTrail Yes Yes No
Rotation Optional: automatic (period 90–2,560 days, default 365) and on-demand (§6) Every year, can't be changed Decided by the service
Monthly fee $1 per key (prorated hourly) None None
Request charges Yes, beyond the free tier Yes (some services pay them for you) None

Developer angle

# Symmetric key for application data, plus an alias the code refers to
aws kms create-key --description "orders service data" --key-spec SYMMETRIC_DEFAULT --key-usage ENCRYPT_DECRYPT
aws kms create-alias --alias-name alias/orders --target-key-id 1234abcd-12ab-34cd-56ef-1234567890ab

# Who manages this key, what is it, can it be used right now?
aws kms describe-key --key-id alias/orders \
  --query 'KeyMetadata.[KeyManager,KeySpec,KeyUsage,KeyState,Origin,MultiRegion]'

# Asymmetric signing key; export the public key for offline verification
aws kms create-key --key-spec ECC_NIST_P256 --key-usage SIGN_VERIFY --description "release signing"
aws kms get-public-key --key-id alias/release-signing --query PublicKey --output text | base64 --decode > release-pub.der

Traps

Practice questions

  1. A developer builds a reporting service that stores sensitive data in a DynamoDB table. The security team requires that every use of the encryption key is visible in CloudTrail and that the team can restrict who may use the key through its key policy. Which encryption option meets these requirements?

    • A. Keep the default encryption with the AWS owned key.
    • B. Switch the table to the AWS managed key aws/dynamodb.
    • C. Switch the table to a customer managed KMS key.
    • D. Encrypt each item client-side with a key stored in an environment variable.
  2. A company must let external partners encrypt files that only the company can decrypt. The partners cannot call AWS APIs. Which TWO actions meet the requirement? (Select TWO.)

    • A. Create an asymmetric RSA KMS key with key usage ENCRYPT_DECRYPT.
    • B. Create a symmetric KMS key and give the partners its key material.
    • C. Download the public key with GetPublicKey and distribute it to the partners.
    • D. Create an HMAC KMS key and send the partners its MAC tags.
    • E. Create an ECC KMS key with key usage SIGN_VERIFY and share its public key.
Answers
  1. C. Only a customer managed key gives the team its own key policy while every use is still logged in CloudTrail. A is invisible in CloudTrail; B is logged, but its key policy is set by DynamoDB and can't be edited; D leaves a long-term key in configuration and loses KMS auditing.
  2. A, C. With an RSA encrypt/decrypt key, anyone holding the public key can encrypt offline while decryption stays inside KMS. B is impossible because KMS never exports symmetric key material; D produces authentication tags, not ciphertext; E creates a signing key, which can't encrypt.

2. Key policies grants and cross account access

Concept

Exam facts

Developer angle

Key policy statement that lets an application role in account 444455556666 use the key only through S3 in us-east-1 and only for one bucket (with S3 Bucket Keys the context value becomes the bucket ARN, §5):

{
  "Sid": "OrdersAppViaS3Only",
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::444455556666:role/OrdersAppRole" },
  "Action": ["kms:Decrypt", "kms:GenerateDataKey"],
  "Resource": "*",
  "Condition": {
    "StringEquals": { "kms:ViaService": "s3.us-east-1.amazonaws.com" },
    "StringLike": { "kms:EncryptionContext:aws:s3:arn": "arn:aws:s3:::orders-bucket/*" }
  }
}

The role's IAM policy in account 444455556666 must allow the same actions on the full key ARN. Day-to-day commands:

aws kms get-key-policy --key-id 1234abcd-12ab-34cd-56ef-1234567890ab --policy-name default --output text > policy.json
aws kms put-key-policy --key-id 1234abcd-12ab-34cd-56ef-1234567890ab --policy-name default --policy file://policy.json
aws kms create-grant --key-id arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab \
  --grantee-principal arn:aws:iam::111122223333:role/BatchWorker \
  --operations Decrypt GenerateDataKey \
  --constraints EncryptionContextSubset={tenant=acme}
aws kms list-grants --key-id 1234abcd-12ab-34cd-56ef-1234567890ab
aws kms retire-grant --grant-token "$GRANT_TOKEN"

Traps

Practice questions

  1. A Lambda function in account B reads objects from an S3 bucket in account A. The objects are encrypted with SSE-KMS using a customer managed key in account A. The bucket policy and the function's role already allow s3:GetObject, but the call fails with an AccessDenied error that comes from KMS. What should the developer do?

    • A. Re-encrypt the objects with the AWS managed key aws/s3.
    • B. Allow kms:Decrypt for the role in the key policy and in the role's IAM policy.
    • C. Create a new KMS key in account B and give the function's role a grant on it.
    • D. Add a kms:ViaService condition for lambda.us-east-1.amazonaws.com to the role's IAM policy.
  2. A security engineer must make sure that a customer managed key is used by the OrdersAppRole role only when Amazon S3 in us-east-1 calls KMS on the role's behalf, and only for objects in the orders-bucket bucket. Which TWO condition keys should the key policy statement use? (Select TWO.)

    • A. kms:GrantIsForAWSResource set to true
    • B. kms:ViaService with the value s3.us-east-1.amazonaws.com
    • C. kms:CallerAccount set to the account ID
    • D. kms:EncryptionContext:aws:s3:arn matching arn:aws:s3:::orders-bucket/*
    • E. aws:SourceIp set to the application's address range
Answers
  1. B. Cross-account KMS use needs the key policy in the owning account (account A) and an IAM allow in the caller's account (account B). A fails because AWS managed keys can't be used from another account; C creates a key that never encrypted these objects; D narrows access instead of granting the missing permission (and here S3, not Lambda, calls KMS).
  2. B, D. kms:ViaService limits use to S3 requests in us-east-1, and S3's encryption context pins the bucket. A applies only to grant operations; C limits the account but neither the service nor the bucket; E doesn't describe requests that S3 makes for the role.

3. KMS API operations and the 4 KB limit

Concept

Exam facts

Operation What it does Limits and notes Permission
Encrypt Encrypts up to 4,096 bytes with a symmetric key RSA keys take less: RSA_2048 190 bytes (OAEP-SHA-256) or 214 (SHA-1), RSA_3072 318/342, RSA_4096 446/470; ciphertext up to 6,144 bytes kms:Encrypt
Decrypt Returns plaintext up to 4,096 bytes KeyId optional for symmetric ciphertext (recommended); required, with EncryptionAlgorithm, for asymmetric kms:Decrypt
ReEncrypt Decrypts and re-encrypts inside KMS; plaintext never reaches the caller Changes the key or the encryption context; source and destination keys may be in different accounts kms:ReEncryptFrom (source) + kms:ReEncryptTo (destination)
GenerateDataKey Returns a data key in plaintext and encrypted under the KMS key KeySpec AES_256/AES_128 or NumberOfBytes 1–1,024 (exactly one of them); symmetric KMS keys only kms:GenerateDataKey
GenerateDataKeyWithoutPlaintext Returns only the encrypted data key For a component that stores keys now and decrypts one (Decrypt) when it needs it kms:GenerateDataKeyWithoutPlaintext
GenerateDataKeyPair (and …WithoutPlaintext) Asymmetric data key pair Own small quotas (RSA_2048: 20 per second) kms:GenerateDataKeyPair
GenerateRandom 1–1,024 random bytes Uses no KMS key; optionally generated in a CloudHSM key store kms:GenerateRandom (IAM policy)
Sign/Verify, GenerateMac/VerifyMac, DeriveSharedSecret Signatures, HMAC tags, ECDH Key usage must match the operation matching kms: action

Developer angle

# Encrypt a small secret (fileb:// passes raw bytes; the output is base64, so decode it before storing)
aws kms encrypt --key-id alias/orders --plaintext fileb://db-password.txt \
  --encryption-context app=billing,env=prod \
  --query CiphertextBlob --output text | base64 --decode > db-password.enc

# Decrypt with the same context; KeyId is optional for symmetric keys but explicit is safer
aws kms decrypt --ciphertext-blob fileb://db-password.enc --key-id alias/orders \
  --encryption-context app=billing,env=prod \
  --query Plaintext --output text | base64 --decode

# Move the ciphertext to another key without exposing the plaintext
aws kms re-encrypt --ciphertext-blob fileb://db-password.enc \
  --source-encryption-context app=billing,env=prod \
  --destination-key-id alias/orders-v2 --destination-encryption-context app=billing,env=prod \
  --query CiphertextBlob --output text | base64 --decode > db-password-v2.enc

aws kms generate-random --number-of-bytes 32 --query Plaintext --output text
# Permission check only: an allowed call ends in DryRunOperationException
aws kms decrypt --ciphertext-blob fileb://db-password.enc --encryption-context app=billing,env=prod --dry-run
import boto3

kms = boto3.client("kms", region_name="us-east-1")
blob = kms.encrypt(KeyId="alias/orders", Plaintext=b"s3cr3t",
                   EncryptionContext={"app": "billing"})["CiphertextBlob"]
try:
    kms.decrypt(CiphertextBlob=blob, KeyId="alias/orders",
                EncryptionContext={"app": "Billing"})  # different case: decryption fails
except kms.exceptions.InvalidCiphertextException:
    print("the encryption context must match exactly")

Traps

Practice questions

  1. After a refactor, an application that stores tokens encrypted with KMS gets InvalidCiphertextException on every Decrypt call for existing tokens. The refactor renamed the encryption context key from tenantId to tenant; new tokens encrypt and decrypt correctly. What is the MOST likely fix for the existing tokens?

    • A. Add the KeyId parameter to every Decrypt call.
    • B. Grant the application role kms:ReEncrypt* on the key.
    • C. Enable automatic key rotation on the key and retry the failed Decrypt calls.
    • D. Pass the original context key tenantId with the same values to Decrypt.
  2. A data team must move archived ciphertext from KMS key A to KMS key B. Security requires that the plaintext never reaches the migration script. Which TWO actions meet the requirement? (Select TWO.)

    • A. Call Decrypt with key A and then Encrypt with key B in the script.
    • B. Allow kms:Decrypt on key B for the script's role.
    • C. Call ReEncrypt with DestinationKeyId set to key B.
    • D. Enable automatic key rotation on key A.
    • E. Allow kms:ReEncryptFrom on key A and kms:ReEncryptTo on key B for the script's role.
Answers
  1. D. Decryption must present exactly the context bound at encryption time. A is optional for symmetric ciphertext and doesn't bypass the context check; B doesn't affect Decrypt; C never fixes a context mismatch and doesn't change existing ciphertext.
  2. C, E. ReEncrypt decrypts and re-encrypts inside KMS and needs ReEncryptFrom on the source key plus ReEncryptTo on the destination key. A exposes plaintext to the script; B is the wrong permission on the wrong key; D keeps the data under key A.

4. Envelope encryption and the Encryption SDK

Concept

Exam facts

Developer angle

Manual envelope encryption with boto3 and the cryptography package:

import os
import boto3
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

kms = boto3.client("kms")
context = {"app": "orders", "doc": "invoice-42"}
data = b"...several megabytes of invoice data..."

# Encrypt: one KMS call; the payload never leaves the process
dk = kms.generate_data_key(KeyId="alias/orders", KeySpec="AES_256", EncryptionContext=context)
nonce = os.urandom(12)
envelope = {"key": dk["CiphertextBlob"], "nonce": nonce,
            "body": AESGCM(dk["Plaintext"]).encrypt(nonce, data, None)}
del dk  # drop the plaintext data key as soon as possible

# Decrypt: KMS only ever sees the small encrypted data key
plain_key = kms.decrypt(CiphertextBlob=envelope["key"], EncryptionContext=context)["Plaintext"]
assert AESGCM(plain_key).decrypt(envelope["nonce"], envelope["body"], None) == data

The Encryption SDK for Python does the same in two calls, here with data key caching:

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy

client = aws_encryption_sdk.EncryptionSDKClient(
    commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT)
provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(
    key_ids=["arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"])
caching_cmm = aws_encryption_sdk.CachingCryptoMaterialsManager(
    master_key_provider=provider,
    cache=aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=100),
    max_age=300.0,
    max_messages_encrypted=1000)

ciphertext, _ = client.encrypt(source=b"telemetry record", materials_manager=caching_cmm,
                               encryption_context={"stream": "telemetry"})
plaintext, header = client.decrypt(source=ciphertext, materials_manager=caching_cmm)
assert header.encryption_context["stream"] == "telemetry"

Traps

Practice questions

  1. A media service must encrypt 200 MB video files client-side before uploading them to Amazon S3, using a KMS key that the security team controls, with the fewest KMS API calls per file. Which approach should the developer use?

    • A. Split each file into 4 KB chunks and call Encrypt on every chunk before uploading it.
    • B. Call GenerateDataKey per file, encrypt locally, and store the encrypted data key with the object.
    • C. Call GenerateRandom to create a 32-byte key, encrypt locally, and store the key in the object metadata.
    • D. Upload the file unencrypted and call ReEncrypt on the stored object.
  2. A telemetry pipeline that uses the AWS Encryption SDK receives ThrottlingException errors from GenerateDataKey during traffic peaks. Which TWO actions address the problem? (Select TWO.)

    • A. Enable data key caching with a caching cryptographic materials manager and short security thresholds.
    • B. Switch the wrapping key to an asymmetric RSA KMS key.
    • C. Call Encrypt for every record instead of using data keys.
    • D. Request a higher Cryptographic operations (symmetric) request rate quota in Service Quotas.
    • E. Set the commitment policy to ForbidEncryptAllowDecrypt.
Answers
  1. B. One data key per file means one KMS call, no size limit, and plaintext that never leaves the process. A makes over 50,000 calls per file; C stores an unprotected key next to the data; D sends plaintext to S3, and ReEncrypt works on KMS ciphertext, not on objects.
  2. A, D. Caching reuses data keys so fewer GenerateDataKey calls happen, and the shared symmetric quota is adjustable. B has lower quotas, and asymmetric KMS keys can't generate data keys; C multiplies the number of calls; E turns off key commitment without reducing calls.

5. Request quotas throttling and S3 Bucket Keys

Concept

Exam facts

Quota (requests per second, per account and Region) Value
Symmetric cryptographic operations, shared (Encrypt, Decrypt, ReEncrypt, GenerateDataKey, GenerateDataKeyWithoutPlaintext, GenerateRandom, GenerateMac, VerifyMac) 10,000 default · 20,000 in us-east-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, eu-central-1, eu-west-2, eu-south-2 · 100,000 in us-east-1, us-west-2, eu-west-1
RSA keys (shared) 1,000
ECC and SM2 keys (shared) 1,000
ML-DSA keys (shared) 1,000
GenerateDataKeyPair RSA_2048 / ECC curves 20 / 100
Each custom key store (CloudHSM or external) 1,800 (not adjustable for CloudHSM key stores)
Management APIs (examples) CreateKey 5 · DescribeKey 2,000 · PutKeyPolicy 15

Developer angle

# SSE-KMS with an S3 Bucket Key for new objects
aws s3api put-bucket-encryption --bucket orders-bucket --server-side-encryption-configuration '{
  "Rules": [{
    "ApplyServerSideEncryptionByDefault": {
      "SSEAlgorithm": "aws:kms",
      "KMSMasterKeyID": "arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"},
    "BucketKeyEnabled": true}]}'

# An existing SSE-S3 or SSE-KMS object switches to the Bucket Key in place (no copy; ETag and Last-Modified kept)
aws s3api update-object-encryption --bucket orders-bucket --key 2026/report.csv \
  --object-encryption '{"SSEKMS": {
    "KMSKeyArn": "arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
    "BucketKeyEnabled": true}}'

# Objects that UpdateObjectEncryption rejects (unencrypted, SSE-C, DSSE-KMS) pick it up only when rewritten
# (an SSE-C source also needs --copy-source-sse-customer-algorithm and --copy-source-sse-customer-key)
aws s3api copy-object --bucket orders-bucket --key 2022/report.csv --copy-source orders-bucket/2022/report.csv \
  --server-side-encryption aws:kms \
  --ssekms-key-id arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab \
  --bucket-key-enabled

# Current KMS cryptographic quotas in this Region
aws service-quotas list-service-quotas --service-code kms \
  --query 'Quotas[?contains(QuotaName, `Cryptographic operations`)].[QuotaName,Value]'
import boto3
from botocore.config import Config

# Adaptive retry mode adds client-side rate limiting on top of exponential backoff
kms = boto3.client("kms", config=Config(retries={"max_attempts": 10, "mode": "adaptive"}))

Traps

Practice questions

  1. An ingestion service in eu-west-3 uploads about 12,000 small objects per second to a bucket that uses SSE-KMS with a customer managed key, and uploads fail intermittently with ThrottlingException errors from KMS. The team wants the MOST cost-effective fix that requires no application code changes. What should the developer do?

    • A. Switch the uploader to client-side encryption that calls Encrypt for each object.
    • B. Change the bucket's default encryption to DSSE-KMS.
    • C. Enable an S3 Bucket Key in the bucket's default encryption configuration.
    • D. Move the KMS key into an AWS CloudHSM key store.
  2. A developer enables S3 Bucket Keys on a bucket that uses SSE-KMS. Which TWO results should the developer expect? (Select TWO.)

    • A. Existing objects are re-encrypted automatically in the background.
    • B. KMS CloudTrail events for new objects show the bucket ARN as the encryption context.
    • C. Objects can now use DSSE-KMS at a lower KMS cost.
    • D. Every PutObject call must now include an extra request header.
    • E. S3 sends fewer requests to KMS, which lowers KMS request costs.
Answers
  1. C. A Bucket Key removes most per-object KMS calls without touching code (12,000 per second is above the 10,000 default in eu-west-3). A adds even more KMS calls plus code changes; B isn't compatible with Bucket Keys and still calls KMS per object; D lowers the ceiling to 1,800 per second per key store and adds HSM cost.
  2. B, E. The bucket-level key cuts traffic to KMS, and CloudTrail records the bucket ARN as the context. A is wrong because only new writes use the Bucket Key automatically; C is unsupported; D is unnecessary because the bucket setting applies by default.

6. Key rotation deletion and multi Region keys

Concept

Exam facts

Key Automatic rotation On-demand rotation Manual rotation (new key + alias)
Customer managed, symmetric, AWS_KMS origin Optional, off by default; RotationPeriodInDays 90–2,560 (default 365) Yes, up to 25 times per key (not adjustable), independent of the schedule Possible
Customer managed, symmetric, imported material (EXTERNAL) No Yes, after importing new material (state Pending rotation) Yes
Asymmetric, HMAC, keys in custom key stores No No The only option
AWS managed Every year; can't be changed or triggered No No
AWS owned Decided by the owning service No No

Developer angle

Management operations take a key ID or key ARN, not an alias:

KEY_ID=1234abcd-12ab-34cd-56ef-1234567890ab
aws kms enable-key-rotation --key-id "$KEY_ID" --rotation-period-in-days 180
aws kms get-key-rotation-status --key-id "$KEY_ID"
aws kms rotate-key-on-demand --key-id "$KEY_ID"
aws kms list-key-rotations --key-id "$KEY_ID"

# Manual rotation for an HMAC key: new key, move the alias, keep the old key enabled
NEW_KEY=$(aws kms create-key --key-spec HMAC_256 --key-usage GENERATE_VERIFY_MAC --query KeyMetadata.KeyId --output text)
aws kms update-alias --alias-name alias/session-mac --target-key-id "$NEW_KEY"

# Safe retirement: disable, watch CloudTrail for DisabledException, then schedule deletion
aws kms disable-key --key-id 0987dcba-09fe-87dc-65ba-ab0987654321
aws kms schedule-key-deletion --key-id 0987dcba-09fe-87dc-65ba-ab0987654321 --pending-window-in-days 30

# Multi-Region: primary in us-east-1, replica in eu-west-1
aws kms create-key --multi-region --description "global orders" --region us-east-1
aws kms replicate-key --key-id mrk-1234abcd12ab34cd56ef1234567890ab --replica-region eu-west-1 --region us-east-1

Traps

Practice questions

  1. A compliance rule requires the key material of a symmetric customer managed KMS key to change every 180 days. Applications must keep working without code or configuration changes. Which solution meets the requirement with the LEAST operational overhead?

    • A. Create an EventBridge schedule that invokes a Lambda function to call RotateKeyOnDemand every 180 days.
    • B. Create a new KMS key every 180 days and move the alias to it with UpdateAlias.
    • C. Switch the applications to the AWS managed key of the service.
    • D. Run aws kms enable-key-rotation with --rotation-period-in-days 180.
  2. An application encrypts records client-side in us-east-1 with the AWS Encryption SDK. During a Regional outage it must decrypt the same ciphertext in eu-west-1 without the data having been re-encrypted beforehand. Which TWO steps meet the requirement? (Select TWO.)

    • A. Use ReEncrypt to copy the existing single-Region key into eu-west-1.
    • B. Encrypt with a multi-Region primary key in us-east-1 that is replicated to eu-west-1 with ReplicateKey.
    • C. Configure the application in eu-west-1 to decrypt with the replica key in eu-west-1.
    • D. Convert the existing single-Region key into a multi-Region key.
    • E. Store the ciphertext in an S3 bucket that replicates to eu-west-1 with Cross-Region Replication.
Answers
  1. D. A custom automatic rotation period does it with no extra components, and the key ID stays the same. A works but adds a scheduler and a function to maintain and burns on-demand rotations (25 per key) on a routine job; B needs work every 180 days and old keys to keep; C can't meet a 180-day rule because AWS managed keys rotate yearly.
  2. B, C. Related multi-Region keys share key material, so the replica in eu-west-1 decrypts ciphertext produced in us-east-1. A is impossible because ReEncrypt works on ciphertext, not on keys; D isn't supported; E copies the ciphertext, but decrypting it would still need the key in us-east-1.

7. CloudHSM versus KMS and custom key stores

Concept

Exam facts

AWS KMS AWS CloudHSM
Who owns the HSMs AWS, shared fleet behind the service You: dedicated HSMs in your VPC
Validation FIPS 140-3 Level 3 HSMs hsm2m.medium FIPS 140-3 Level 3 (hsm1.medium FIPS 140-2 Level 3); cluster in FIPS or non-FIPS mode, fixed at creation
Access control Key policies, IAM, grants HSM users and passwords managed inside the cluster; IAM only governs the cluster-management API
AWS service integration Native Through a KMS custom key store, or your own software (SSL/TLS offload, Oracle TDE, certificate authority keys, Redshift)
Availability Managed, 99.999 % SLA You add HSMs; AWS recommends at least two HSMs in different AZs for production
Pricing $1 per key-month + requests; free tier Per HSM per hour, no upfront fee, no free tier

Developer angle

aws cloudhsmv2 describe-clusters --query 'Clusters[].[ClusterId,State,HsmType,Mode]'

# Connect KMS to the cluster, then create keys whose material lives in your HSMs
aws kms create-custom-key-store --custom-key-store-name orders-hsm \
  --cloud-hsm-cluster-id cluster-1a23b4cdefg \
  --trust-anchor-certificate file://customerCA.crt --key-store-password "$KMSUSER_PASSWORD"
aws kms connect-custom-key-store --custom-key-store-id cks-1234567890abcdef0
aws kms describe-custom-key-stores --custom-key-store-id cks-1234567890abcdef0 \
  --query 'CustomKeyStores[0].ConnectionState'
aws kms create-key --origin AWS_CLOUDHSM --custom-key-store-id cks-1234567890abcdef0 --description "regulated data"

Traps

Practice questions

  1. A regulator requires a bank's encryption keys to be generated and used only in single-tenant HSMs that the bank controls, and the bank wants key operations to stay on the AWS network. EBS volumes and RDS databases must still be encrypted through their normal KMS integration. Which solution meets these requirements?

    • A. Create the KMS keys in a custom key store backed by an AWS CloudHSM cluster.
    • B. Create customer managed KMS keys with imported key material.
    • C. Use the AWS managed keys aws/ebs and aws/rds.
    • D. Create an external key store that points to an HSM in the bank's data center.
  2. A team is evaluating AWS CloudHSM for a payment application. Which TWO statements are correct? (Select TWO.)

    • A. CloudHSM includes a free tier for development clusters.
    • B. Access to keys stored in CloudHSM is granted with KMS key policies.
    • C. Keys in a CloudHSM key store support automatic rotation.
    • D. The team creates and manages the HSM users, and AWS can't recover keys if their credentials are lost.
    • E. AWS recommends at least two HSMs in different Availability Zones for production workloads.
Answers
  1. A. A CloudHSM key store keeps the material in single-tenant HSMs inside AWS while EBS and RDS keep calling KMS. B keeps the material in the multi-tenant KMS HSMs; C gives the bank no control at all; D sends every key operation outside AWS through a proxy.
  2. D, E. Users and credentials belong to the customer, and high availability needs HSMs in two AZs. A is wrong because there is no free tier; B confuses CloudHSM with KMS; C is wrong because custom key stores don't support automatic rotation.

8. SSM Parameter Store

Concept

Exam facts

Standard (default) Advanced
Parameters per account and Region 10,000 100,000
Value size 4 KB 8 KB
Parameter policies No Yes (up to 10 per parameter)
Share with other accounts (AWS RAM) No Yes (read-only for consumers)
SecureString encryption KMS Encrypt/Decrypt directly Envelope encryption with the Encryption SDK (GenerateDataKey)
Storage price No charge $0.05 per parameter-month (prorated hourly)
Change tier Can be upgraded Can't be downgraded: delete and recreate

Developer angle

aws ssm put-parameter --name /orders/prod/db-url --type String --value "jdbc:mysql://orders-db:3306/orders"
aws ssm put-parameter --name /orders/prod/db-password --type SecureString --key-id alias/orders --value 'example-only'
aws ssm get-parameter --name /orders/prod/db-password --with-decryption --query Parameter.Value --output text
aws ssm get-parameters-by-path --path /orders/prod --recursive --with-decryption
aws ssm label-parameter-version --name /orders/prod/db-url --parameter-version 3 --labels live
aws ssm get-parameter --name /orders/prod/db-url:live
aws ssm put-parameter --name /orders/prod/partner-cert --type SecureString --tier Advanced \
  --value file://partner-cert.pem --overwrite \
  --policies '[{"Type":"Expiration","Version":"1.0","Attributes":{"Timestamp":"2027-01-31T00:00:00.000Z"}},
               {"Type":"ExpirationNotification","Version":"1.0","Attributes":{"Before":"14","Unit":"Days"}}]'
aws ssm update-service-setting --setting-value true \
  --setting-id arn:aws:ssm:us-east-1:111122223333:servicesetting/ssm/parameter-store/high-throughput-enabled

Least-privilege read policy for a function that loads one path and decrypts it with one key:

{
  "Version": "2012-10-17",
  "Statement": [
    { "Effect": "Allow",
      "Action": ["ssm:GetParameter", "ssm:GetParameters", "ssm:GetParametersByPath"],
      "Resource": ["arn:aws:ssm:us-east-1:111122223333:parameter/orders/prod",
                   "arn:aws:ssm:us-east-1:111122223333:parameter/orders/prod/*"] },
    { "Effect": "Allow",
      "Action": "kms:Decrypt",
      "Resource": "arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
      "Condition": { "StringLike": {
        "kms:EncryptionContext:PARAMETER_ARN": "arn:aws:ssm:us-east-1:111122223333:parameter/orders/prod/*" } } }
  ]
}

Traps

Practice questions

  1. At deployment, 400 containers start at the same time and each reads 20 parameters with GetParameter. Many reads fail with ThrottlingException: Rate exceeded. Which change fixes the problem with the fewest code changes?

    • A. Change every parameter to the advanced tier and redeploy the containers.
    • B. Move the parameters to Secrets Manager and read them with BatchGetSecretValue.
    • C. Turn on the Parameter Store higher throughput setting in the Region.
    • D. Rename the parameters into a deeper hierarchy.
  2. A team must store a 6 KB partner certificate as an encrypted parameter and receive an EventBridge notification 14 days before the parameter is deleted at its expiry date. Which TWO actions meet the requirements? (Select TWO.)

    • A. Create the parameter as an advanced-tier SecureString.
    • B. Create the parameter as a standard-tier SecureString and attach the policies.
    • C. Use a String parameter with an AllowedPattern that matches certificates.
    • D. Attach a NoChangeNotification policy with After set to 14 days.
    • E. Attach an Expiration policy and an ExpirationNotification policy with Before set to 14 days.
Answers
  1. C. Higher throughput raises GetParameter from the shared 40 per second to 10,000 per second with no code change. A changes storage limits, not the request rate; B requires code changes and still needs caching; D has no effect on throughput.
  2. A, E. 6 KB needs the advanced tier, which also enables parameter policies, and the two policies delete the parameter and warn 14 days ahead. B fails both the 4 KB limit and the policy requirement; C isn't encrypted; D fires when the value hasn't changed for a period, not before expiry.

9. Secrets Manager basics and Parameter Store comparison

Concept

Exam facts

Need Parameter Store Secrets Manager
Plain configuration, feature values, AMI IDs Best fit (standard tier is free) Overkill
Encryption Optional (SecureString) Always (KMS)
Automatic rotation No (build it with EventBridge + Lambda) Built in (managed or Lambda)
Database credential integration No RDS, Aurora, Redshift, DocumentDB
Cross-account access Advanced parameters through AWS RAM Resource policy + customer managed key
Multi-Region No replication Replica secrets
Maximum value 4 KB / 8 KB 64 KB
Price Free (standard) or $0.05 per advanced parameter-month $0.40 per secret-month + API calls
Reading one through the other /aws/reference/secretsmanager/<id> returns a secret —

Developer angle

aws secretsmanager create-secret --name prod/orders/db --kms-key-id alias/orders \
  --secret-string '{"engine":"mysql","host":"orders-db.cluster-abc.us-east-1.rds.amazonaws.com","port":3306,"username":"app","password":"example-only"}'
aws secretsmanager get-secret-value --secret-id prod/orders/db --query SecretString --output text
aws secretsmanager describe-secret --secret-id prod/orders/db --query VersionIdsToStages
aws secretsmanager put-resource-policy --secret-id prod/orders/db --block-public-policy \
  --resource-policy file://allow-reporting-account.json
aws secretsmanager delete-secret --secret-id prod/orders/db --recovery-window-in-days 7
aws secretsmanager restore-secret --secret-id prod/orders/db
import json
import botocore.session
from aws_secretsmanager_caching import SecretCache, SecretCacheConfig

client = botocore.session.get_session().create_client("secretsmanager")
cache = SecretCache(config=SecretCacheConfig(), client=client)  # refreshes secrets hourly by default

def handler(event, context):
    creds = json.loads(cache.get_secret_string("prod/orders/db"))
    # open the database connection with creds["host"], creds["username"] and creds["password"]
    return {"db_host": creds["host"]}

Traps

Practice questions

  1. A Lambda function calls GetSecretValue on every invocation to fetch database credentials, and the API cost and latency are now significant. The team wants the smallest change that keeps the credentials out of the function configuration. What should the developer do?

    • A. Copy the secret into an encrypted Lambda environment variable as part of each deployment.
    • B. Add the AWS Parameters and Secrets Lambda Extension and read the secret from localhost.
    • C. Move the credentials to a standard-tier String parameter in Parameter Store.
    • D. Increase the function's memory setting to 1,024 MB.
  2. An application in account B must read a secret stored in account A. The application role in account B already has an IAM policy that allows secretsmanager:GetSecretValue and kms:Decrypt on the correct ARNs. Which TWO additional steps are required? (Select TWO.)

    • A. Replicate the secret into account B with ReplicateSecretToRegions.
    • B. Add a kms:ViaService condition for Secrets Manager to the role's IAM policy.
    • C. Attach a resource policy to the secret that allows the account B role to call GetSecretValue.
    • D. Encrypt the secret with a customer managed key whose key policy allows the account B role to use kms:Decrypt.
    • E. Keep the aws/secretsmanager key and create a KMS grant for the account B role.
Answers
  1. B. The extension caches the secret locally (TTL up to 300 seconds), needing only a layer and a localhost call. A exposes the value in the configuration and goes stale after rotation; C stores a credential unencrypted; D may shorten each call but keeps paying for one call per invocation.
  2. C, D. Cross-account access needs the secret's resource policy and a customer managed key the other account may use. A replicates across Regions, not accounts; B narrows the role's permissions instead of adding the missing ones; E fails because AWS managed keys can't be used by other accounts.

10. Secrets Manager rotation and replication

Concept

Exam facts

Developer angle

# Let Secrets Manager invoke the rotation function, then rotate every 6 hours within a 2-hour window
aws lambda add-permission --function-name orders-db-rotator --statement-id SecretsManager \
  --action lambda:InvokeFunction --principal secretsmanager.amazonaws.com --source-account 111122223333
aws secretsmanager rotate-secret --secret-id prod/orders/db \
  --rotation-lambda-arn arn:aws:lambda:us-east-1:111122223333:function:orders-db-rotator \
  --rotation-rules '{"ScheduleExpression": "rate(6 hours)", "Duration": "2h"}'

# When is the next rotation, and which version holds which label?
aws secretsmanager describe-secret --secret-id prod/orders/db \
  --query '{Next: NextRotationDate, Stages: VersionIdsToStages}'

# Replicate to a DR Region with a key that lives there; promote the replica if the primary Region fails
aws secretsmanager replicate-secret-to-regions --secret-id prod/orders/db \
  --add-replica-regions Region=eu-west-1,KmsKeyId=alias/orders-dr
aws secretsmanager stop-replication-to-replica --secret-id prod/orders/db --region eu-west-1

Traps

Practice questions

  1. A rotation function for an Aurora secret runs in private subnets that have no NAT gateway. The function's role and the database security groups are correct, but every rotation attempt times out in the create_secret step. Which change fixes the problem MOST securely?

    • A. Increase the function's timeout and memory.
    • B. Move the function to public subnets that route through the VPC's internet gateway.
    • C. Switch the secret to the alternating users strategy.
    • D. Create an interface VPC endpoint for Secrets Manager in the function's VPC.
  2. A high-availability service must rotate its database credentials every 6 hours, and no login may fail during a rotation. Which TWO configuration choices meet these requirements? (Select TWO.)

    • A. Set AutomaticallyAfterDays to 0.25.
    • B. Use the alternating users rotation strategy with a separate superuser secret.
    • C. Use the single user rotation strategy.
    • D. Set the rotation schedule to rate(6 hours).
    • E. Set the rotation schedule to rate(2 hours).
Answers
  1. D. A private endpoint gives the function a path to Secrets Manager without opening the VPC to the internet. A can't fix missing network access; B doesn't work because Lambda network interfaces never get public IP addresses, and it would expose the function's network; C changes which user rotates, not connectivity.
  2. B, D. Alternating users always leaves one valid credential, and rate(6 hours) sets the interval. A is invalid because the days field takes whole days (minimum 1); C allows brief login failures; E is below the four-hour minimum.

11. CloudFormation dynamic references and RDS managed secrets

Concept

Exam facts

Type Syntax Notes
ssm {{resolve:ssm:/path/name}} or {{resolve:ssm:/path/name:4}} Version optional (latest at each create or update); public parameters work (e.g. the AL2023 AMI); a version is mandatory in the Parameters section; no labels; no parameters shared from other accounts
ssm-secure {{resolve:ssm-secure:/path/name}} or {{resolve:ssm-secure:/path/name:3}} Only in supported properties (e.g. AWS::RDS::DBInstance/DBCluster MasterUserPassword, AWS::IAM::User LoginProfile Password, AWS::Redshift::Cluster MasterUserPassword, AWS::ElastiCache::ReplicationGroup AuthToken, Directory Service passwords); never stored or returned by CloudFormation; no other accounts, labels or public parameters; not in the China Regions
secretsmanager {{resolve:secretsmanager:secret-id:SecretString:json-key:version-stage:version-id}} Any resource property, not just a supported list as for ssm-secure, but the general limits below still apply (not in custom resources, EC2 UserData or AWS::CloudFormation::Init); secret-id is the name (same account) or the full ARN (required for another account); SecretString is the only and default type; omit json-key for the whole string; omit stage and ID for AWSCURRENT

Developer angle

Resources:
  DbSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Description: Master credentials for the orders database
      KmsKeyId: alias/orders
      GenerateSecretString:
        SecretStringTemplate: '{"username": "orders_admin"}'
        GenerateStringKey: password
        PasswordLength: 32
        ExcludeCharacters: '"@/\'
  OrdersDb:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: mysql
      DBInstanceClass: db.t3.micro
      AllocatedStorage: '20'
      MasterUsername: !Sub '{{resolve:secretsmanager:${DbSecret}:SecretString:username}}'
      MasterUserPassword: !Sub '{{resolve:secretsmanager:${DbSecret}:SecretString:password}}'
  DbSecretAttachment:
    Type: AWS::SecretsManager::SecretTargetAttachment
    Properties:
      SecretId: !Ref DbSecret
      TargetId: !Ref OrdersDb
      TargetType: AWS::RDS::DBInstance
  ReportsDb:
    Type: AWS::RDS::DBInstance
    Properties:
      Engine: postgres
      DBInstanceClass: db.t3.micro
      AllocatedStorage: '20'
      MasterUsername: reports_admin
      ManageMasterUserPassword: true
  OnboardingUser:
    Type: AWS::IAM::User
    Properties:
      LoginProfile:
        Password: '{{resolve:ssm-secure:/iam/onboarding/initial-password:3}}'
        PasswordResetRequired: true
  WebServer:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t3.micro
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}'

Traps

Practice questions

  1. A template must set an RDS master password to the password key of the Secrets Manager secret prod/orders/db, which is in the same account, without the value ever appearing in the template or in stack parameters. Which property value should the developer use?

    • A. '{{resolve:secretsmanager:prod/orders/db:SecretString:password}}'
    • B. '{{resolve:ssm-secure:prod/orders/db:password}}'
    • C. A NoEcho stack parameter that holds the password as its default value in the template
    • D. !GetAtt DbSecret.SecretString
  2. A team wants RDS for PostgreSQL master credentials that no person ever sees, that rotate automatically with no rotation code to maintain, and that are encrypted with the team's own KMS key. Which TWO template settings meet these requirements? (Select TWO.)

    • A. Set ManageMasterUserPassword to true on the AWS::RDS::DBInstance resource.
    • B. Add a custom rotation Lambda function and an AWS::SecretsManager::RotationSchedule for the master password.
    • C. Set MasterUserSecret with KmsKeyId pointing to the team's customer managed key.
    • D. Reference an ssm-secure parameter for MasterUserPassword and rotate it with an EventBridge rule.
    • E. Pass the password as a NoEcho parameter at each deployment.
Answers
  1. A. The secretsmanager reference with SecretString:password resolves the JSON key at deploy time and nothing is stored in the stack. B points ssm-secure at a Secrets Manager name with an invalid version segment; C still makes someone supply the password and stores it in the template; D isn't an attribute that returns a secret value.
  2. A, C. ManageMasterUserPassword gives RDS-managed generation and rotation, and MasterUserSecret.KmsKeyId picks the customer managed key. B adds code to maintain; D needs custom rotation and a human-chosen first value; E exposes the password to whoever deploys.

12. CloudWatch Logs encryption and CodeBuild secrets

Concept

Exam facts

Developer angle

KEY_ARN=arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
aws logs create-log-group --log-group-name /orders/api --kms-key-id "$KEY_ARN"
aws logs associate-kms-key --log-group-name /orders/worker --kms-key-id "$KEY_ARN"
aws logs describe-log-groups --log-group-name-prefix /orders --query 'logGroups[].[logGroupName,kmsKeyId]'
aws logs disassociate-kms-key --log-group-name /orders/worker

Key policy statement for CloudWatch Logs, limited to one log group:

{
  "Sid": "AllowLogsForOrdersApi",
  "Effect": "Allow",
  "Principal": { "Service": "logs.us-east-1.amazonaws.com" },
  "Action": ["kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:Describe*"],
  "Resource": "*",
  "Condition": { "ArnEquals": {
    "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:us-east-1:111122223333:log-group:/orders/api" } }
}

Buildspec that pulls its secrets at build time:

version: 0.2
env:
  variables:
    APP_ENV: staging
  parameter-store:
    DB_URL: /orders/staging/db-url
  secrets-manager:
    DB_PASSWORD: staging/orders/db:password
    NPM_TOKEN: shared/npm-token:token
phases:
  build:
    commands:
      - ./scripts/run-integration-tests.sh

Traps

Practice questions

  1. A developer runs aws logs associate-kms-key for an existing log group and receives AccessDeniedException. The customer managed key's policy contains only the default statement for the account. What should the developer do?

    • A. Replace the key with an asymmetric RSA key.
    • B. Associate the key from the CloudWatch console instead of the CLI, in the log group's settings.
    • C. Allow logs.<region>.amazonaws.com in the key policy; give the caller kms:DescribeKey.
    • D. Enable automatic rotation on the key and run associate-kms-key again.
  2. A buildspec needs a database password from Secrets Manager and an internal API URL from Parameter Store. Neither value may appear in the project configuration, and the password must not appear in build logs. Which TWO steps meet the requirements? (Select TWO.)

    • A. Define both values under env/variables as plaintext.
    • B. List the password under exported-variables for the later pipeline stages.
    • C. Map the password with env/secrets-manager and allow secretsmanager:GetSecretValue for the service role.
    • D. Print the base64-encoded password in a build command to confirm that it was retrieved.
    • E. Map the URL with env/parameter-store and allow ssm:GetParameters for the service role.
Answers
  1. C. CloudWatch Logs needs key policy access for its service principal (scoped by the log group's encryption context), and the caller needs kms:DescribeKey. A isn't supported because log groups take symmetric keys only; B can't associate a key with an existing group; D grants no permission.
  2. C, E. Both mappings fetch the values at build time with the right service-role permissions, and CodeBuild masks the exact secret value. A exposes the values; B isn't allowed for Secrets Manager values; D prints a transformed value that masking won't catch.

13. Nitro Enclaves and attested KMS requests

Concept

Exam facts

Developer angle

aws ec2 run-instances --image-id ami-0abcdef1234567890 --instance-type m5.xlarge \
  --enclave-options 'Enabled=true' --iam-instance-profile Name=CardProcessorProfile

nitro-cli build-enclave --docker-uri card-processor:latest --output-file card-processor.eif
nitro-cli run-enclave --cpu-count 2 --memory 2048 --eif-path card-processor.eif
nitro-cli describe-enclaves

Key policy statement: the parent's role may decrypt only on behalf of an enclave built from one approved image:

{
  "Sid": "DecryptOnlyInsideTheCardEnclave",
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::111122223333:role/CardProcessorRole" },
  "Action": ["kms:Decrypt", "kms:GenerateDataKey"],
  "Resource": "*",
  "Condition": { "StringEqualsIgnoreCase": {
    "kms:RecipientAttestation:ImageSha384": "<image measurement printed by nitro-cli build-enclave>" } }
}

Traps

Practice questions

  1. A payment company processes card numbers inside a Nitro enclave. Only an enclave started from one approved image may decrypt the card data key; code on the parent instance, which uses the same IAM role, must get a denial. What should the developer add to the KMS key policy?

    • A. A kms:RecipientAttestation:ImageSha384 condition that matches the approved image.
    • B. A condition on kms:ViaService set to ec2.us-east-1.amazonaws.com.
    • C. A condition on aws:SourceVpc that matches the instance's VPC.
    • D. A grant for the parent instance role that is limited by an EncryptionContextEquals constraint.
  2. A developer starts an enclave with nitro-cli run-enclave --debug-mode to troubleshoot it. Every Decrypt request with an attestation document is now denied by a key policy that checks PCR0, although the same image works in production. Which TWO statements are correct? (Select TWO.)

    • A. The key policy also needs a kms:ViaService condition for Amazon EC2.
    • B. Enclaves started in debug mode produce attestation documents whose PCRs are all zeros.
    • C. The parent needs a larger instance type for attestation to work.
    • D. The instance must require IMDSv2 before KMS accepts attestation documents.
    • E. Starting the enclave without --debug-mode lets the attestation condition match again.
Answers
  1. A. An attestation condition is satisfied only by requests that carry a signed document from an enclave built from that image. B concerns requests that a service makes and doesn't identify the enclave; C would also match the parent instance; D can't tell the enclave and the parent apart.
  2. B, E. Debug-mode enclaves are deliberately non-attestable (zeroed PCRs), so a production-mode launch matches again. A, C and D have nothing to do with the attestation measurements.

Quick decision rules

Choosing the mechanism (§1, §3, §4, §7)

Permissions and errors (§2, §3)

Throughput (§5)

Keys over time (§6)

Secrets (§8–§12)

Changed vs older material

Learn the Current column; older practice material may still show the Older material may say value. Once you confirm them, the same rows go to notes/current-facts.md with their verification date.

Topic Older material may say Current (verified 2026-10-12) Source
§1 · AWS managed key charges and status AWS managed keys are free No monthly fee, but every use is billed as a KMS request (some services pay it); a legacy type: since 2021 new services encrypt with AWS owned keys AWS docs
§1 · KMS key types Symmetric AES-256 or asymmetric RSA/ECC only Also HMAC keys (April 2022), ECC key agreement (June 2024), ML-DSA post-quantum signing (June 2025), Ed25519 (November 2025) AWS docs
§4 · Encryption SDK languages Java, Python, C, JavaScript (plus the CLI) C, C#/.NET, Java, JavaScript, Python, Rust, Go (plus the CLI) AWS docs
§5 · Symmetric cryptographic request quota 5,500/s default; 10,000/s in six Regions; 30,000/s in us-east-1, us-west-2, eu-west-1 10,000/s default; 20,000/s in us-east-2, ap-southeast-1, ap-southeast-2, ap-northeast-1, eu-central-1, eu-west-2, eu-south-2; 100,000/s in us-east-1, us-west-2, eu-west-1 (July 2024) AWS docs
§5 · RSA request quota 500/s 1,000/s (shared) AWS docs
§5 · ECC request quota 300/s 1,000/s (shared, ECC and SM2) AWS docs
§5 · Bucket Keys for existing objects Existing objects get a Bucket Key only when rewritten with CopyObject UpdateObjectEncryption switches SSE-S3 and SSE-KMS objects to SSE-KMS with a Bucket Key in place, keeping ETag and Last-Modified; unencrypted, SSE-C and DSSE-KMS objects still need CopyObject AWS docs
§6 · AWS managed key rotation Every three years (about 1,095 days) Every year (about 365 days) since May 2022; can't be changed or triggered AWS docs
§6 · Customer managed key rotation period Fixed: once a year RotationPeriodInDays 90–2,560, default 365 (April 2024); symmetric keys with AWS_KMS material only AWS docs
§6 · Key rotation pricing Every rotation adds $1/month Only the first and second rotations add $1/month each (prorated hourly); later rotations aren't billed (April 2024) What's New
§6 · On-demand rotation Not available; imported keys only by repointing an alias RotateKeyOnDemand, at most 25 per key (not adjustable), schedule unchanged (April 2024); also symmetric imported material (June 2025) and multi-Region imported material (November 2025); not asymmetric, HMAC or custom key store keys AWS docs
§6 · Using a key in another Region A KMS key can't be used outside its Region Multi-Region keys (June 2021) share key ID and material, so ciphertext encrypted in one Region decrypts with the related key in another AWS docs
§7 · KMS HSM validation FIPS 140-2 Level 3 FIPS 140-3 Level 3 AWS docs
§7 · CloudHSM validation FIPS 140-2 Level 3 hsm2m.medium FIPS 140-3 Level 3 (hsm1.medium FIPS 140-2 Level 3); FIPS or non-FIPS cluster mode, fixed at creation AWS FAQ
§7 · SSE-C availability SSE-C (for example with CloudHSM-held keys) works on any bucket Disabled by default for new general purpose buckets since April 2026; enable with PutBucketEncryption BlockedEncryptionTypes = NONE, otherwise HTTP 403 AWS docs
§8 · Amazon Linux public AMI parameter /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 Amazon Linux 2 end of support 2026-06-30; use AL2023 parameters such as al2023-ami-kernel-default-x86_64 AWS FAQ
§10 · Secrets Manager rotation frequency Days only, at most once a day As often as every four hours with rate()/cron(), rotation window at least one hour, UTC; rate() up to 999 days AWS docs
§10 · Rotation mechanism Rotation always runs a Lambda function Managed rotation (no Lambda) for RDS, Aurora, Redshift and DocumentDB master credentials, ECS Service Connect certificates and managed external secrets; Lambda for other secrets AWS docs
§11 · ssm/ssm-secure reference version The version is part of the syntax Optional: latest version at each create or update; mandatory only for ssm references in the Parameters section AWS docs
§12 · CloudWatch Logs key association in the console The console can't associate a KMS key with a log group AWS documents that the console can't associate a key with an existing log group (use associate-kms-key); console support at creation ⚠️ unverified AWS docs