AWS for DevOps — KMS Encryption

2 minute read

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

Updated: