Rotate Master Keys with AWS KMS

Learn how to use AWS KMS to rotate master keys in this practical Cloud security essentials tutorial. Understand the core concept, step-by-step process, and best practices for key rotation, with a hands-on exercise and troubleshooting tips.

Focus: use aws kms to rotate master keys

Sponsored

If you’re like most teams, your master keys live in AWS KMS and you haven't thought about rotation since the day you created them. That’s exactly the problem this lesson solves: key rotation isn’t a one-time configuration task — it’s an ongoing security habit. When you use AWS KMS to rotate master keys, you shrink the window of exposure for encrypted data and simplify compliance audits. By the end of this lesson, you’ll understand automatic vs. manual rotation, how to enable it in the console and via the AWS CLI, and how to avoid the classic pitfalls that leave your keys static for years.

The problem this lesson solves

Master keys are the crown jewels of your encryption posture. If a key is compromised — through leaked credentials, insider access, or a misconfigured policy — an attacker can decrypt everything it ever protected, unless you rotate it. Without rotation, your ciphertext stays bound to a single key version forever. A breach at any point in the future retroactively exposes historical data.

Compliance frameworks like PCI DSS, HIPAA, and SOC 2 explicitly require periodic key rotation. Auditors look for evidence that you change keys on a defined schedule. If you can’t prove rotation, you may fail an audit or, worse, face a data breach that could have been mitigated.

The pain is real: manual rotation is error-prone, and many teams delay it because they worry about breaking applications. This lesson removes that fear by showing you exactly how AWS KMS rotation works and how to implement it safely — without downtime or code changes.

Core concept / mental model

Think of a KMS master key as a key ring with multiple versions of the same key. Each version is a distinct cryptographic key that can encrypt and decrypt data. When you call Encrypt, AWS KMS uses the current version (the primary key) to produce ciphertext. When you call Decrypt, KMS looks at the ciphertext’s metadata to find which version encrypted it and uses that version to decrypt.

This design is what makes rotation transparent: rotating simply adds a new version to the key ring and makes it the default for encryption. Existing ciphertext still decrypts because the old version remains available.

Two rotation modes:

  • Automatic rotation (annual or custom): AWS KMS creates a new version automatically on a schedule. No downtime, no code changes.
  • Manual rotation: You create a new key and update your applications to use it via aliases. More control but more work.

Pro tip: Automatic rotation is the easiest way to satisfy compliance and keep your keys fresh. Manual rotation should be reserved for scenarios where you need immediate, granular control — for example, after a suspected compromise.

How it works step by step

Here’s the logical sequence AWS KMS follows when you enable automatic rotation:

  1. Create a symmetric customer master key (CMK) in AWS KMS (or use an existing one) with appropriate key policy.
  2. Enable automatic rotation on that CMK — either in the console or using the EnableKeyRotation API.
  3. AWS KMS schedules rotation: For keys with a single-region, it creates a new key version immediately and then a new version every year (or every custom rotation period if you’re using the newer RotationPeriodInDays parameter). AWS KMS marks the new version as the primary for all encryption operations.
  4. Encryption now uses the newest version — but decryption continues to work for any ciphertext encrypted under older versions, because KMS retains all previous versions until the key is deleted.
  5. Audit and verify via CloudTrail or DescribeKey to confirm rotation occurred.

For manual rotation, the process is different: you must create a new CMK, update your application secrets (e.g., in Secrets Manager or env vars) to reference the new key ID or alias, and finally retire or schedule deletion of the old key. That’s why automatic rotation is usually the better default.

What exactly gets rotated?

  • Key material: The underlying cryptographic bytes change with each new version.
  • Key ID and ARN: These stay the same — that’s why you don’t update your apps.
  • Key policy: Not affected by rotation.

What doesn’t get rotated?

  • Aliases: They always point to the same key ID, so your code can keep using the alias.
  • Grants and key policies remain unchanged.

Hands-on walkthrough

Let’s get practical. You’ll use the AWS CLI (make sure you have aws configured with appropriate IAM permissions: kms:EnableKeyRotation, kms:DescribeKey, kms:CreateKey, kms:ScheduleKeyDeletion).

1. Create a symmetric key with automatic rotation enabled

# Create a symmetric encryption key
export KEY_ID=$(aws kms create-key --key-usage ENCRYPT_DECRYPT --description "My rotating master key" --query KeyMetadata.KeyId --output text)

# Enable automatic rotation with a custom period (e.g., 180 days)
aws kms enable-key-rotation --key-id $KEY_ID --rotation-period-in-days 180

echo "Rotating key created: $KEY_ID"

Expected output (after echo):

Rotating key created: 1234abcd-12ab-34cd-56ef-1234567890ab

2. Verify rotation status

aws kms get-key-rotation-status --key-id $KEY_ID

Output (truncated):

{
    "KeyRotationEnabled": true,
    "RotationPeriodInDays": 180
}

3. Simulate encryption and decryption across a rotation

import boto3
import os

# Create a KMS client
kms = boto3.client('kms', region_name='us-east-1')

key_id = os.environ['KEY_ID']  # Set to your key ID

# Encrypt some data
plaintext = b"Sensitive payroll data"
response = kms.encrypt(KeyId=key_id, Plaintext=plaintext)
ciphertext_blob = response['CiphertextBlob']
print("Encrypted ciphertext length:", len(ciphertext_blob))

# Now, manually rotate the key (simulate by creating a new key version — in practice, wait for automatic rotation)
# For educational purposes, we'll call EnableKeyRotation again (which is idempotent)
kms.enable_key_rotation(KeyId=key_id, RotationPeriodInDays=180)

# Decrypt the old ciphertext — it should still work!
decrypt_response = kms.decrypt(CiphertextBlob=ciphertext_blob)
print("Decrypted plaintext:", decrypt_response['Plaintext'].decode())

Expected output:

Encrypted ciphertext length: 128
Decrypted plaintext: Sensitive payroll data

The ciphertext created before rotation still decrypts because KMS retains the old key version. That’s the magic of transparent rotation.

4. Automate with Infrastructure as Code (CloudFormation snippet)

Resources:
  RotatingKey:
    Type: AWS::KMS::Key
    Properties:
      Enabled: true
      EnableKeyRotation: true
      PendingWindowInDays: 30
      KeyPolicy:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
            Action: 'kms:*'
            Resource: '*'

This CloudFormation template creates a key with automatic rotation enabled — perfect for “rotation by default” in your infrastructure.

Compare options / when to choose what

Aspect Automatic Rotation Manual Rotation
Effort Zero after enabled High — create new key, update apps, retire old
Downtime None Typically none if aliases used, but risky if not
Compliance Satisfies most auditor requirements Satisfies if documented and executed
Control Based on schedule (1–365 days) Full control over timing
Cost Low (new version is free; you pay for storage/use) Same, but operational cost + risk
Use case Most production keys Compliance-driven immediate rotation, compromise response

Recommendation: Use automatic rotation for all symmetric CMKs that encrypt data at rest. Use manual rotation only when you need to rotate immediately (e.g., key compromise) or for asymmetric keys where rotation is manual by design.

Variations to consider

  • Custom rotation period: AWS KMS now supports RotationPeriodInDays (between 90 and 2560 days) — you’re no longer locked to 365 days. Use 90–180 days for higher security posture.
  • Alias-based key management: Always alias your keys (e.g., alias/prod-db-key) and rotate the underlying key, not the alias. Your applications remain untouched.
  • AWS-managed keys: For AWS services like S3, you can enable automatic rotation on AWS-managed keys as well (though you have less control). For full control, use your own customer-managed keys.

Troubleshooting & edge cases

"KeyRotationEnabled is false even after enabling"

This usually happens if you’re using an asymmetric key or a key imported from AWS CloudHSM. Automatic rotation is only supported for symmetric customer-managed keys. For imported key material, you must perform manual rotation by creating a new key and re-importing.

"I see multiple key versions — is that a problem?"

No — it’s expected. KMS retains all versions for decryption. However, if you exceed 100 versions, you must delete old versions manually to avoid limits. Use ListKeyVersions to monitor and clean up.

"Decrypt fails with InvalidKeyId"

This happens when you manually rotate by creating a new key and then try to decrypt with the wrong key ID. Always decrypt using the original key ID or alias — KMS remembers the key material via the version metadata, but the key ID must match the one used for encryption.

"My stack uses Terraform — how do I enable rotation?"

resource "aws_kms_key" "app" {
  enable_key_rotation = true
  rotation_period_in_days = 180
}

The same principles apply: enable rotation at creation time to avoid drift.

"Compliance requires rotation every 90 days"

Set --rotation-period-in-days 90 in the CLI or rotation_period_in_days = 90 in Terraform. AWS KMS will rotate exactly every 90 days.

What you learned & what's next

You now know how to use AWS KMS to rotate master keys — both automatic and manual approaches. You understand the mental model of key versions, how rotation is transparent to applications, and you can verify rotation status with the CLI and infrastructure-as-code. You’ve also seen how to troubleshoot the most common rotation failures.

These concepts directly support your Cloud security essentials path: master key rotation reduces IAM blast radius (because keys are ephemeral) and is a core security control for any production environment.

Next up: you’ll explore how to set up cross-account key usage — allowing other accounts in your AWS organization to use your KMS keys securely via key policies. That’s the next logical step after mastering rotation, because it extends your encryption governance across accounts.

Before you move on: Review the practice recap below and try the exercise on your own — you’ll thank yourself later.

Practice recap

Try this mini-exercise: Create a new KMS key with automatic rotation set to 90 days, encrypt a test file, then use the AWS CLI to confirm rotation is enabled. Next, simulate a manual rotation by creating a second key and decryption your file using the original key — observe that decryption still works because of key versions. Finally, write a short CloudFormation template that creates a key with rotation enabled; this will save you time in future projects.

Common mistakes

  • Forgetting to enable rotation on existing keys — new keys can have rotation enabled at creation, but many teams never retrofit old keys.
  • Trying to enable automatic rotation on asymmetric keys or imported keys, which is not supported — you must rotate those manually.
  • Changing the key ID in your application after manual rotation instead of using aliases, which breaks decryption for existing ciphertext.
  • Ignoring key version limits (100 versions max) — old versions accumulate and can cause your key to hit the limit, so prune them periodically.
  • Setting a rotation period too long (e.g., 3650 days) — compliance requires more frequent rotation, so use 90–365 days depending on your needs.

Real-world use cases

  • Encrypting a production database (e.g., RDS) with a customer-managed KMS key that auto-rotates every 180 days to meet audit requirements.
  • Storing secrets in AWS Secrets Manager encrypted with a CMK that rotates annually; the application doesn't change because it uses an alias.
  • Running a multi-account setup where a central KMS key is rotated automatically and used by member accounts via key policies for data-at-rest encryption.

Key takeaways

  • KMS key rotation is transparent: it adds a new key version, and old ciphertext continues to decrypt.
  • Automatic rotation is the recommended default for symmetric customer-managed keys — zero downtime and low effort.
  • Manual rotation is necessary for asymmetric keys, imported keys, or immediate compromise response.
  • Use aliases for your keys so application code never changes when keys rotate.
  • Custom rotation periods (90–365 days) let you align with your compliance timeline.
  • Verify rotation with get-key-rotation-status and monitor key versions to avoid hitting limits.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.