AWS Data Encryption Architecture — Overview
Data encryption is the largest topic on the SCS-C03 exam (Domain 5: 18%). Every scenario involves choosing between KMS and CloudHSM, selecting the right key type, designing cross-account key access, and implementing rotation. This post covers the complete encryption decision framework — from key hierarchy to cross-account patterns to exam traps around key policies.
Auto-created per service
Cannot manage rotation
Cannot use cross-account
Free (no monthly fee)
Full key policy control
Cross-account sharing ✅
Auto-rotation (configurable)
$1/month + $0.03/10K requests
You manage durability
Can set expiration
Manual rotation only
Delete & re-import
KMS vs CloudHSM — Detailed Comparison
| Feature | AWS KMS | CloudHSM |
|---|---|---|
| FIPS Level | FIPS 140-2 Level 2 (Level 3 in some modules) | FIPS 140-2 Level 3 |
| Tenancy | Multi-tenant (shared infrastructure) | Single-tenant (dedicated HSM in your VPC) |
| Key Access | AWS manages HSM; you control via key policy | You have full exclusive control (AWS cannot access keys) |
| Key Types | Symmetric (AES-256), Asymmetric (RSA, ECC) | Symmetric, Asymmetric, + custom algorithms |
| Integration | Native AWS service integration (S3, EBS, RDS, etc.) | Custom application integration, Oracle TDE, SSL/TLS offload |
| Cross-account | Yes (via key policy + IAM) | Not directly (must share via network/VPC peering) |
| HA | Built-in (multi-AZ by default) | You must deploy cluster (min 2 HSMs across AZs) |
| Cost | $1/key/month + API calls | ~$1.50/hr per HSM (~$1,100/month per HSM) |
KMS Key Policy — The Critical Exam Topic
KMS key policies are the #1 exam trap. Unlike all other AWS resources, KMS keys have their own resource policy that MUST explicitly grant access — IAM policies alone are insufficient unless the key policy allows it.
- Default key policy: Allows the root principal to perform all actions → enables IAM policies to control access
- Without root principal statement: IAM policies cannot grant access to the key (even AdministratorAccess won’t work!)
- Key administrators: Can manage the key (enable/disable, delete, rotate) but CANNOT use it for encrypt/decrypt
- Key users: Can use the key for encrypt/decrypt/generate data key operations
- Grants: Delegated, temporary access to a key (used by AWS services internally, e.g., EBS attaching encrypted volume)
Cross-Account KMS Key Access
Two things must be true for cross-account KMS access:
- Key policy in Account A must allow Account B’s root (or specific role):
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_B:root"} - IAM policy in Account B must allow the role to use the key:
"Resource": "arn:aws:kms:region:ACCOUNT_A:key/key-id"
Exam trap: If the key policy only lists specific principals (no root principal), IAM policies in Account A won’t work either. The key policy is the primary gatekeeper.
Key Rotation
| Key Type | Auto-Rotation | Manual Rotation | Exam Notes |
|---|---|---|---|
| AWS Managed | Automatic (every year) — cannot change | N/A | You cannot control rotation period |
| Customer Managed (KMS-generated) | Optional, configurable (90-2560 days) | Create new key + update alias | Old key material kept (decrypt old data). Key ID unchanged. Only new data uses new material. |
| Imported Key Material | ❌ Not supported | Delete → re-import new material | Must manage externally. Can set expiration date. Use alias for transparent rotation. |
| CloudHSM | You manage entirely | Application-level rotation | Full customer responsibility |
Encryption Patterns — At Rest
| Service | SSE Options | Key Decision |
|---|---|---|
| S3 | SSE-S3 (default), SSE-KMS, SSE-C, CSE | SSE-KMS for audit trail (CloudTrail logs each decrypt). SSE-C when you manage keys externally. CSE for client-side. |
| EBS | AES-256 (KMS) | Enable default encryption per region. Snapshots inherit key. Cross-account: re-encrypt with shared key. |
| RDS | AES-256 (KMS) | Must enable at creation (cannot encrypt existing). Encrypted snapshots → encrypted restore. Cross-region: re-encrypt with target region key. |
| DynamoDB | AWS owned, AWS managed, Customer managed | Customer managed for cross-account access control and audit. AWS owned is free. |
Encryption in Transit
- ELB: Configure security policies (TLS 1.2+ enforced). Use ACM certificates. ALB terminates TLS, can re-encrypt to backend.
- S3: Bucket policy with
aws:SecureTransport: falsedenies HTTP. Forces HTTPS only. - RDS:
rds.force_ssl = 1(MySQL) orrds.force_ssl = true(PostgreSQL). Download RDS CA bundle. - API Gateway: HTTPS only by default. Can configure mutual TLS (mTLS) with custom domain.
- VPC: VPN (IPsec) or PrivateLink for private connectivity. All inter-region VPC peering is encrypted.
Envelope Encryption (Data Key Pattern)
- How it works: KMS generates a Data Encryption Key (DEK). Plaintext DEK encrypts your data. KMS encrypts the DEK with the CMK. Store encrypted DEK alongside encrypted data.
- Why: KMS has a 4KB limit on direct encrypt. Envelope encryption allows encrypting any size data. Only the small DEK crosses the network to KMS.
- GenerateDataKey: Returns both plaintext DEK (use to encrypt) and encrypted DEK (store alongside data)
- Decrypt flow: Send encrypted DEK to KMS → get plaintext DEK → decrypt data locally
- Exam relevance: “Encrypt 1GB file with KMS” → must use envelope encryption (GenerateDataKey), NOT Encrypt API
Exam Tips
| Exam | Key Points |
|---|---|
| SCS-C03 | “FIPS 140-2 Level 3” → CloudHSM. “Cross-account encryption” → Customer managed KMS key + key policy allowing other account. “Audit who decrypted” → SSE-KMS (CloudTrail logs Decrypt calls). “Imported key material” → manual rotation only, you manage durability. “Key policy allows root principal” = enables IAM policies. “Encrypt large file with KMS” → envelope encryption (GenerateDataKey). “Cannot encrypt existing RDS” → snapshot, copy with encryption, restore. |
AWS Certification Exam Practice Questions
Question 1:
A company stores sensitive financial data in S3. Compliance requires that all decryption events are logged in CloudTrail, the encryption key can be disabled immediately if compromised, and only specific IAM roles can decrypt. Which encryption configuration meets ALL these requirements?
- SSE-S3 (Amazon S3-managed keys)
- SSE-KMS with an AWS managed key (aws/s3)
- SSE-KMS with a customer managed key and restrictive key policy
- SSE-C (customer-provided keys)
Show Answer
Answer: C — Customer managed KMS key provides: (1) CloudTrail logging of every Decrypt/Encrypt call. (2) Ability to disable the key immediately (renders all data inaccessible). (3) Key policy controls exactly which roles can decrypt. AWS managed keys (B) log decrypt events but cannot be disabled and don’t allow custom key policy. SSE-S3 (A) doesn’t log individual decrypt events. SSE-C (D) requires customer to manage key delivery on every request.
Question 2:
Account A has an encrypted EBS snapshot that needs to be shared with Account B. The snapshot is encrypted with a customer managed KMS key. What steps are required for Account B to use this snapshot?
- Share the snapshot with Account B. Account B copies it using their own KMS key. No key policy change needed.
- Modify the KMS key policy to allow Account B access. Share the snapshot. Account B creates a volume or copies with their own key.
- Create an unencrypted copy of the snapshot, then share the unencrypted version with Account B.
- Export the KMS key to Account B using key material import.
Show Answer
Answer: B — For cross-account encrypted snapshot sharing: (1) The KMS key policy must grant Account B permission to use the key (kms:Decrypt, kms:CreateGrant). (2) Share the snapshot with Account B. (3) Account B can then copy the snapshot to their account, re-encrypting with their own CMK. Without key policy change, Account B cannot decrypt the snapshot even after it’s shared. You cannot create an unencrypted copy of an encrypted snapshot (C is wrong).
Question 3:
A company’s compliance team requires that encryption keys used for sensitive workloads are stored in hardware that AWS personnel cannot access, while still using the KMS API for integration with AWS services. Which configuration achieves this?
- KMS with customer managed keys (standard)
- KMS with imported key material
- KMS custom key store backed by CloudHSM cluster
- Client-side encryption with keys stored in Secrets Manager
Show Answer
Answer: C — Custom key store connects KMS to your CloudHSM cluster. You get the KMS API (integrates with S3, EBS, RDS, etc.) but keys are generated and stored in your single-tenant CloudHSM (AWS personnel cannot access). Standard KMS (A) uses multi-tenant AWS-managed HSMs. Imported keys (B) still reside in AWS HSMs after import. This is the best-of-both-worlds approach.
Question 4:
A developer tries to use a KMS key to encrypt data but receives “AccessDeniedException.” Their IAM policy has kms:* on the key ARN. The key policy only contains a statement allowing the key administrator to manage the key. What is the issue?
- The IAM policy must specify the exact actions (kms:Encrypt) not wildcard
- The key policy does not include the root principal statement, so IAM policies cannot grant access
- The developer needs to be added as a key administrator
- KMS keys require explicit Deny removal before access works
Show Answer
Answer: B — This is the #1 KMS exam trap. KMS key policies are the primary access control. If the key policy does not include a statement allowing the account’s root principal (which enables IAM policies to work), then NO IAM policy can grant access — even kms:* will fail. The fix: add {"Effect": "Allow", "Principal": {"AWS": "arn:aws:iam::ACCOUNT:root"}, "Action": "kms:*", "Resource": "*"} to the key policy.
Question 5:
A company needs to encrypt a 50MB file using KMS. When they call the kms:Encrypt API with the file, they receive an error that the payload exceeds the 4KB limit. How should they encrypt this file?
- Split the file into 4KB chunks and encrypt each chunk separately with kms:Encrypt
- Use kms:GenerateDataKey to get a data encryption key, encrypt the file locally with the plaintext key, store the encrypted key alongside the encrypted file
- Increase the KMS payload limit through a service quota increase request
- Use CloudHSM instead, which has no payload size limit
Show Answer
Answer: B — This is envelope encryption. KMS’s Encrypt API has a 4KB payload limit. For larger data: (1) Call GenerateDataKey → get plaintext DEK + encrypted DEK. (2) Use plaintext DEK to encrypt the 50MB file locally (AES-256). (3) Discard plaintext DEK from memory. (4) Store encrypted DEK alongside encrypted file. To decrypt: send encrypted DEK to KMS (Decrypt API) → get plaintext DEK → decrypt file locally. The 4KB limit cannot be increased (C is wrong).
Related Posts
- Centralized Logging Architecture
- Security Services Architecture
- Multi-Account Architecture
- Zero Trust Architecture
- Secrets & Certificate Management
- Incident Response Architecture
References
- AWS KMS Concepts — AWS Docs
- KMS Key Policies — AWS Docs
- KMS and IAM Security Policies — AWS Security Blog
- CloudHSM User Guide — AWS Docs
Frequently Asked Questions
When should I use CloudHSM vs KMS?
Use KMS for most workloads — it integrates natively with 100+ AWS services, is fully managed, and costs $1/key/month. Use CloudHSM when you need: FIPS 140-2 Level 3 compliance, single-tenant HSM (regulatory requirement), full exclusive key control (AWS cannot access), or custom cryptographic algorithms. You can combine both via KMS Custom Key Store.
Can I use one KMS key across multiple accounts?
Yes, but both the key policy AND an IAM policy must allow it. The key policy grants the other account’s root principal (or specific role) access. Then an IAM policy in the consuming account allows the role to call KMS. Without BOTH, cross-account access fails. AWS managed keys (aws/s3, aws/ebs) cannot be shared cross-account — only customer managed keys.
What happens when I rotate a KMS key?
AWS creates new key material but keeps the old material. The key ID and ARN don’t change. New data encrypts with new material. Old data still decrypts fine (KMS tracks which version encrypted each ciphertext). You don’t need to re-encrypt existing data. This is automatic and transparent — no application changes needed.