AWS for DevOps — KMS Encryption
13.4 — KMS Encryption
AWS Key Management Service (KMS) lets you create and manage encryption keys. Most AWS services integrate with KMS for encrypting data at rest.
Real-World Analogy
KMS is like a master locksmith who manages all the keys to your building. You don’t carry the keys yourself — you ask the locksmith to lock and unlock doors for you. The locksmith keeps the keys in a tamper-proof safe (HSM), tracks who used which key, and can revoke access at any time.
Key Types
| Type | Who Manages | Cost | Use Case |
|---|---|---|---|
| AWS Managed Keys | AWS | Free | Default encryption (S3, EBS, RDS) |
| Customer Managed Keys (CMK) | You | $1/month + API calls | Custom policies, rotation, cross-account |
| AWS Owned Keys | AWS (shared) | Free | Some AWS services internally |
Creating a Customer Managed Key
# Create a symmetric encryption key
$ aws kms create-key \
--description "Production data encryption key" \
--tags TagKey=Environment,TagValue=production
{
"KeyMetadata": {
"KeyId": "abc123-def456-ghi789",
"Arn": "arn:aws:kms:ap-south-1:123456789012:key/abc123-def456-ghi789",
"KeyState": "Enabled",
"KeyUsage": "ENCRYPT_DECRYPT"
}
}
# Create an alias for easy reference
$ aws kms create-alias \
--alias-name alias/production-key \
--target-key-id abc123-def456-ghi789
Encrypting Data
# Encrypt a plaintext string
$ aws kms encrypt \
--key-id alias/production-key \
--plaintext "my-secret-data" \
--output text \
--query CiphertextBlob
AQICAHh...base64...encoded==
# Decrypt it back
$ aws kms decrypt \
--ciphertext-blob fileb://encrypted-data.bin \
--output text \
--query Plaintext | base64 --decode
my-secret-data
Envelope Encryption
For large data, KMS uses envelope encryption (generate a data key, encrypt data locally):
# Generate a data key
$ aws kms generate-data-key \
--key-id alias/production-key \
--key-spec AES_256
{
"CiphertextBlob": "AQICAHh...",
"Plaintext": "base64-encoded-data-key",
"KeyId": "arn:aws:kms:ap-south-1:123456789012:key/abc123"
}
# Use the plaintext data key to encrypt your data locally
# Store the CiphertextBlob alongside the encrypted data
# Discard the plaintext data key from memory
┌─────────────┐
│ KMS Master │
│ Key │ Never leaves KMS
└──────┬───────┘
│ encrypts
▼
┌─────────────┐ encrypts ┌─────────────┐
│ Data Key │────────────────→ │ Your Data │
│ (plaintext) │ │ (encrypted) │
└─────────────┘ └─────────────┘
Discarded after use
Key Policies
# Allow a specific IAM role to use the key
$ aws kms put-key-policy \
--key-id abc123-def456-ghi789 \
--policy-name default \
--policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowRootFullAccess",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "AllowAppRoleEncryptDecrypt",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/app-role"},
"Action": ["kms:Encrypt", "kms:Decrypt", "kms:GenerateDataKey"],
"Resource": "*"
}
]
}'
Automatic Key Rotation
# Enable automatic rotation (rotates every year)
$ aws kms enable-key-rotation --key-id abc123-def456-ghi789
# Check rotation status
$ aws kms get-key-rotation-status --key-id abc123-def456-ghi789
{
"KeyRotationEnabled": true
}
Services That Integrate with KMS
| Service | Default Encryption | KMS Support |
|---|---|---|
| S3 | SSE-S3 (free) | SSE-KMS (CMK) |
| EBS | AES-256 | CMK |
| RDS | AES-256 | CMK |
| Secrets Manager | Always encrypted | CMK |
| DynamoDB | AWS Owned | CMK |
| Lambda (env vars) | AWS Managed | CMK |
| CloudWatch Logs | None | CMK |
Common Mistakes
| Mistake | Why It Hurts | Fix |
|---|---|---|
| Using AWS Managed Keys for everything | No control over key policies | Use CMK for sensitive data |
| Not enabling key rotation | Compliance risk | Enable rotation for all CMKs |
| Overly permissive key policy | Anyone can decrypt data | Grant only kms:Encrypt/kms:Decrypt to specific roles |
| Deleting a key without grace period | Data becomes permanently unreadable | Schedule deletion with 30-day waiting period |
Quick Reference
| Task | Command |
|---|---|
| Create key | aws kms create-key --description "DESC" |
| Create alias | aws kms create-alias --alias-name alias/NAME --target-key-id KEY_ID |
| Encrypt | aws kms encrypt --key-id alias/NAME --plaintext "DATA" |
| Decrypt | aws kms decrypt --ciphertext-blob fileb://FILE |
| Enable rotation | aws kms enable-key-rotation --key-id KEY_ID |
| Generate data key | aws kms generate-data-key --key-id alias/NAME --key-spec AES_256 |
| Schedule deletion | aws kms schedule-key-deletion --key-id KEY_ID --pending-window-in-days 30 |
Next → Security Automation