The Problem
You need to store confidential data in S3. Compliance requires:
- Encryption at rest
- Key usage logged for auditing
- Keys rotated every year
You want the most operationally efficient solution.
The Solution
Use SSE-KMS with a customer-managed key and enable automatic annual rotation. This satisfies all three requirements with a single configuration.
How It Works
Step 1: Create a KMS Key With Rotation Enabled
1
2
3
4
5
6
7
aws kms create-key \
--description "S3 confidential data encryption" \
--key-usage ENCRYPT_DECRYPT \
--origin AWS_KMS
aws kms enable-key-rotation \
--key-id alias/s3-confidential
Automatic rotation generates new key material every 365 days. Old key material stays available so previously encrypted objects can still be decrypted — nothing needs re-encrypting.
Step 2: Set Default Encryption on the Bucket
1
2
3
4
5
6
7
8
9
10
11
aws s3api put-bucket-encryption \
--bucket confidential-data \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "alias/s3-confidential"
},
"BucketKeyEnabled": true
}]
}'
BucketKeyEnabled is important — it dramatically reduces KMS request costs by caching a bucket-level data key.
The Three Requirements Solved
| Requirement | How SSE-KMS Satisfies It |
|---|---|
| Encryption at rest | Every object encrypted with a data key derived from the KMS key |
| Key usage logged | Every Encrypt, Decrypt, GenerateDataKey call goes to CloudTrail |
| Annual key rotation | enable-key-rotation handles rotation automatically |
Why Not the Alternatives?
SSE-C (customer-provided keys) — You send the key with every request. No AWS-side logging, no rotation. Full key management burden falls on you.
SSE-S3 (S3-managed keys) — Simple, but key usage is not logged to CloudTrail for customer visibility. Fails the audit requirement.
SSE-KMS with manual rotation — Meets encryption and audit, but rotation requires generating new keys and re-encrypting — operationally expensive.
Key Takeaways
- SSE-KMS + automatic rotation is the AWS-native answer to encrypt + audit + rotate
- Enable
BucketKeyEnabled: trueto cut KMS costs by up to 99% at scale - Automatic rotation swaps key material every 365 days — old material is retained for decryption
- SSE-S3 does not log key usage to CloudTrail — never use it when auditing is required
- CloudTrail data events must be enabled separately if you want per-object access logging
Never miss a story from us, subscribe to our newsletter