KMS CMK rotation should be enabled
Cryptographic keys that remain static indefinitely increase the blast radius of a compromise. If an attacker obtains key material, every object ever encrypted under that material is exposed. Automatic rotation limits this window: after rotation, new encrypt operations use fresh material, so a leaked key version only decrypts data written during its active period.
AWS handles rotated material transparently. The same key ID continues to work for both old and new ciphertexts, so enabling rotation requires zero application changes. There is no cost increase for rotation itself. Leaving it off provides no operational benefit and silently accumulates risk.
Retrofit consideration
Rotation cannot be enabled on asymmetric keys, HMAC keys, or keys with imported key material. These key types must be rotated manually by creating new keys and re-encrypting data.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "kms" {
source = "pcidss.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "gdpr.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "nist80053.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "nistcsf.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "fedrampmoderate.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "cis.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "cisv80ig1.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "nist800171.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "cisacyberessentials.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "cisv500.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "cccsmedium.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "cfrpart11.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "rbicybersecurity.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "rbiitfnbfc.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "fedramplow.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
module "kms" {
source = "nist80053rev4.compliance.tf/terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
}
If you use terraform-aws-modules/kms/aws, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "kms" {
source = "terraform-aws-modules/kms/aws"
version = ">=4.0.0"
description = "abc123"
enable_key_rotation = true
}
Use AWS provider resources directly. See docs for the resources involved: aws_kms_key.
resource "aws_kms_key" "this" {
deletion_window_in_days = 7
description = "pofix-example-key"
enable_key_rotation = true
}
What this control checks
This control validates that each aws_kms_key resource has enable_key_rotation = true. The argument defaults to false, so any resource that omits it or explicitly sets it to false will fail. The check applies only to symmetric encryption keys with AWS-managed key material (key_spec = "SYMMETRIC_DEFAULT" or omitted, with no imported key material). Asymmetric keys and keys with EXTERNAL origin do not support automatic rotation through this argument and are out of scope.
Common pitfalls
Asymmetric and HMAC keys silently ignored
Setting
enable_key_rotation = trueon an asymmetric key (RSA_2048,ECC_NIST_P256, etc.) or an HMAC key produces an API error at apply time. Automatic rotation is restricted to symmetric keys withkey_spec = "SYMMETRIC_DEFAULT". Those key types require manual rotation by creating a new key and reassigning aliases.Imported key material not eligible
EXTERNALorigin keys don't support automatic rotation. Settingenable_key_rotationon one throwsUnsupportedOperationExceptionat apply time. You have to manually import new material and re-encrypt dependent data.Multi-Region replica keys inherit primary rotation
Rotation for multi-region keys is controlled on the primary, not the replica. Setting
enable_key_rotationon anaws_kms_replica_keyhas no effect. Enable it on the corresponding primaryaws_kms_keyinstead.Custom rotation periods require provider v5.36 or later
AWS supports custom rotation periods (90 to 2560 days) via the
rotation_period_in_daysargument onaws_kms_key, but that argument wasn't available before Terraform AWS provider v5.36. On older versions the period defaults to 365 days regardless of what your compliance framework requires. If you need a shorter cryptoperiod, upgrade the provider and set the value explicitly.
Audit evidence
Auditors look for AWS Config results from the managed rule rotation-enabled showing all CMKs as COMPLIANT. Output from aws kms get-key-rotation-status --key-id <key-id> returning "KeyRotationEnabled": true for each in-scope key is direct point-in-time evidence. CloudTrail EnableKeyRotation API events show when rotation was activated and by whom.
For continuous assurance, a Security Hub export or a third-party compliance dashboard showing this control passing across all accounts and regions over the audit period is generally sufficient. Auditors may also request a full CMK inventory from aws kms list-keys cross-referenced with rotation status to confirm no gaps.
Framework-specific interpretation
PCI DSS v4.0: Requirement 3.6.4 says cryptographic keys must be changed at the end of their defined cryptoperiod. For KMS-encrypted cardholder data, automatic rotation is one way to satisfy that obligation, provided the rotation period aligns with your documented cryptoperiod.
GDPR: Article 32 requires appropriate technical measures to protect personal data. Rotation limits the blast radius if key material is ever disclosed, contributing to data protection by design for EU personal data stored under KMS encryption.
NIST SP 800-53 Rev 5: SC-12 and SC-12(1) require organizations to establish and manage cryptographic keys according to defined lifecycle policies, including rotation at cryptoperiod boundaries. Automatic KMS rotation satisfies that lifecycle requirement for symmetric CMKs. SC-13 is the related cryptographic protection control.
NIST Cybersecurity Framework v2.0: CSF 2.0's Protect function calls for managing data security with appropriate cryptographic safeguards. Key rotation keeps those safeguards from degrading as key material ages, which is the practical point of the outcome.
FedRAMP Moderate Baseline Rev 4: At the Moderate baseline, SC-12 and SC-13 both apply. Enabling KMS rotation is how most FedRAMP implementations satisfy the key lifecycle and cryptoperiod management requirements in those controls, though the authorizing official's documented key management policy governs the specific cryptoperiod length.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
kms_cmk_rotation_enabledAWS Config Managed Rule:
CMK_BACKING_KEY_ROTATION_ENABLEDCheckov Check:
CKV_AWS_7Powerpipe Control:
aws_compliance.control.kms_cmk_rotation_enabledProwler Check:
kms_cmk_rotation_enabledAWS Security Hub Control:
KMS.4KICS Query:
22fbfeac-7b5a-421a-8a27-7a2178bb910bTrivy Check:
AWS-0065
Last reviewed: 2026-03-09