For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/iac_security/iac_rules/cloudformation-aws-default-kms-key-usage.md.
A documentation index is available at /llms.txt.
When storage encryption is enabled for database or analytics clusters or instances, explicitly specifying a customer-managed AWS KMS key prevents use of the AWS-managed default key. Using the AWS-managed default key can limit your ability to enforce key policies, control access, rotate keys, and audit key usage.
In CloudFormation, this applies to AWS::RDS::DBInstance, AWS::RDS::DBCluster, AWS::DocDB::DBCluster, AWS::Neptune::DBCluster, and AWS::Redshift::Cluster. Properties.StorageEncrypted must be true, and Properties.KmsKeyId must be defined and reference a customer-managed AWS KMS key (key ARN, alias, or a Ref to an AWS::KMS::Key). Resources with StorageEncrypted set to true and no KmsKeyId will be flagged.
Define an AWS::KMS::Key and set KmsKeyId (for example, with !Ref) when you need explicit ownership, key policy control, or independent rotation and auditing.
Secure CloudFormation example:
MyKmsKey:Type:AWS::KMS::KeyProperties:Description:"CMK for DB encryption"MyDB:Type:AWS::RDS::DBInstanceProperties:DBInstanceIdentifier:my-dbStorageEncrypted:trueKmsKeyId:!Ref MyKmsKey
Compliant Code Examples
AWSTemplateFormatVersion:2010-09-09Description:RDS Storage EncryptedParameters:SourceDBInstanceIdentifier:Type:StringDBInstanceType:Type:StringSourceRegion:Type:StringResources:MyKey:Type:"AWS::KMS::Key"Properties:KeyPolicy:Version:2012-10-17Id:key-default-1Statement:- Sid:Enable IAM User PermissionsEffect:AllowPrincipal:AWS:!Join- ""- - "arn:aws:iam::"- !Ref "AWS::AccountId"- ":root"Action:"kms:*"Resource:"*"MyDBSmall:Type:"AWS::RDS::DBInstance"Properties:DBInstanceClass:!Ref DBInstanceTypeSourceDBInstanceIdentifier:!Ref SourceDBInstanceIdentifierSourceRegion:!Ref SourceRegionKmsKeyId:!Ref MyKeyStorageEncrypted:true
AWSTemplateFormatVersion:2010-09-09Description:>- AWS CloudFormation Sample TemplateParameters:DBUsername:NoEcho:'true'Description:Username for MySQL database accessType:StringMinLength:'1'MaxLength:'16'AllowedPattern:'[a-zA-Z][a-zA-Z0-9]*'ConstraintDescription:must begin with a letter and contain only alphanumeric characters.DBPassword:NoEcho:'true'Description:Password MySQL database accessType:StringMinLength:'8'MaxLength:'41'AllowedPattern:'[a-zA-Z0-9]*'ConstraintDescription:must contain only alphanumeric characters.Resources:MyKey-0:Type:"AWS::KMS::Key"Properties:KeyPolicy:Version:2012-10-17Id:key-default-1Statement:- Sid:Enable IAM User PermissionsEffect:AllowPrincipal:AWS:!Join- ""- - "arn:aws:iam::"- !Ref "AWS::AccountId"- ":root"Action:"kms:*"Resource:"*"RDSCluster:Type:'AWS::RDS::DBCluster'Properties:MasterUsername:!Ref DBUsernameMasterUserPassword:!Ref DBPasswordDBClusterIdentifier:my-serverless-clusterEngine:auroraEngineVersion:5.6.10aEngineMode:serverlessScalingConfiguration:AutoPause:trueMinCapacity:4MaxCapacity:32SecondsUntilAutoPause:1000KmsKeyId:!Ref MyKey-0StorageEncrypted:true
{"AWSTemplateFormatVersion":"2010-09-09T00:00:00Z","Description":"RDS Storage Encrypted","Parameters":{"SourceDBInstanceIdentifier":{"Type":"String"},"DBInstanceType":{"Type":"String"},"SourceRegion":{"Type":"String"}},"Resources":{"MyKey":{"Type":"AWS::KMS::Key","Properties":{"KeyPolicy":{"Version":"2012-10-17T00:00:00Z","Id":"key-default-1","Statement":[{"Principal":{"AWS":["",["arn:aws:iam::","AWS::AccountId",":root"]]},"Action":"kms:*","Resource":"*","Sid":"Enable IAM User Permissions","Effect":"Allow"}]}}},"MyDBSmall":{"Type":"AWS::RDS::DBInstance","Properties":{"SourceRegion":"SourceRegion","KmsKeyId":"MyKey","StorageEncrypted":true,"DBInstanceClass":"DBInstanceType","SourceDBInstanceIdentifier":"SourceDBInstanceIdentifier"}}}}
Non-Compliant Code Examples
AWSTemplateFormatVersion:2010-09-09Description:>- AWS CloudFormation Sample TemplateParameters:DBUsername:NoEcho:'true'Description:Username for MySQL database accessType:StringMinLength:'1'MaxLength:'16'AllowedPattern:'[a-zA-Z][a-zA-Z0-9]*'ConstraintDescription:must begin with a letter and contain only alphanumeric characters.DBPassword:NoEcho:'true'Description:Password MySQL database accessType:StringMinLength:'8'MaxLength:'41'AllowedPattern:'[a-zA-Z0-9]*'ConstraintDescription:must contain only alphanumeric characters.Resources:RDSCluster1:Type:'AWS::RDS::DBCluster'Properties:MasterUsername:!Ref DBUsernameMasterUserPassword:!Ref DBPasswordDBClusterIdentifier:my-serverless-clusterEngine:auroraEngineVersion:5.6.10aEngineMode:serverlessScalingConfiguration:AutoPause:trueMinCapacity:4MaxCapacity:32SecondsUntilAutoPause:1000StorageEncrypted:true
{"Parameters":{"DBUsername":{"NoEcho":"true","Description":"Username for MySQL database access","Type":"String","MinLength":"1","MaxLength":"16","AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*","ConstraintDescription":"must begin with a letter and contain only alphanumeric characters."},"DBPassword":{"Type":"String","MinLength":"8","MaxLength":"41","AllowedPattern":"[a-zA-Z0-9]*","ConstraintDescription":"must contain only alphanumeric characters.","NoEcho":"true","Description":"Password MySQL database access"}},"Resources":{"RDSCluster1":{"Type":"AWS::RDS::DBCluster","Properties":{"DBClusterIdentifier":"my-serverless-cluster","Engine":"aurora","EngineVersion":"5.6.10a","EngineMode":"serverless","ScalingConfiguration":{"AutoPause":true,"MinCapacity":4,"MaxCapacity":32,"SecondsUntilAutoPause":1000},"StorageEncrypted":true,"MasterUsername":"DBUsername","MasterUserPassword":"DBPassword"}}},"AWSTemplateFormatVersion":"2010-09-09T00:00:00Z","Description":"AWS CloudFormation Sample Template"}
1
2
rulesets:- CloudFormation / AWS # Rules to enforce / AWS.
Request a personalized demo
Get Started with Datadog
Ask AI
AI-generated responses may be inaccurate. Verify important info.