DocumentDB Cluster Storage Encryption
Overview
This check verifies that Amazon DocumentDB clusters have encryption at rest enabled. When enabled, DocumentDB uses 256-bit AES encryption through AWS Key Management Service (KMS) to protect all data in the cluster, including storage volumes, indexes, logs, automated backups, and snapshots.
Encryption is transparent to your applications and requires no code changes.
Risk
Without encryption at rest, your DocumentDB data is stored as plaintext. This creates risk if:
- Storage infrastructure is compromised
- Backups or snapshots are shared improperly or leaked
- Insider threats access the underlying storage
- AWS credentials are stolen and used to copy data
This could result in data breaches, compliance violations (HIPAA, PCI-DSS, GDPR), and exposure of sensitive business information.
Remediation Steps
Prerequisites
- AWS Console access with permissions to create DocumentDB clusters
- (Optional) A KMS key if you want to use a customer-managed key
Required IAM permissions
To create encrypted DocumentDB clusters, you need these permissions:
rds:CreateDBClusterrds:DescribeDBClustersrds:CreateDBInstancekms:DescribeKeykms:CreateGrant(if using customer-managed KMS key)kms:GenerateDataKey(if using customer-managed KMS key)
Important Note
DocumentDB cluster encryption cannot be changed after creation. If you have an unencrypted cluster, you must:
- Create a snapshot of the unencrypted cluster
- Restore the snapshot to a new cluster with encryption enabled
- Update your applications to use the new cluster endpoint
- Delete the old unencrypted cluster
AWS Console Method
Option A: Create a new encrypted cluster
- Open the Amazon DocumentDB console
- Click Clusters in the left navigation
- Click Create
- Configure your cluster settings (identifier, instance class, etc.)
- Expand Show advanced settings
- Under Encryption-at-rest, select Enable encryption
- Choose your KMS key:
- aws/rds - AWS managed key (simplest option)
- Choose a key - Select a customer-managed KMS key
- Complete the remaining configuration and click Create cluster
Option B: Encrypt an existing unencrypted cluster
- Open the Amazon DocumentDB console
- Click Clusters, then select your unencrypted cluster
- Click Actions > Take snapshot
- Enter a snapshot name and click Create
- Wait for the snapshot to complete (status: "available")
- Click Snapshots in the left navigation
- Select your snapshot, click Actions > Restore
- Enter a new cluster identifier
- Expand Show advanced settings
- Under Encryption-at-rest, select Enable encryption
- Choose your KMS key
- Click Restore cluster
- After the new cluster is available, update your application connection strings
- Delete the old unencrypted cluster when you confirm the new one works
AWS CLI (optional)
Create a new encrypted cluster:
aws docdb create-db-cluster \
--db-cluster-identifier my-encrypted-docdb \
--engine docdb \
--master-username myuser \
--master-user-password mypassword123 \
--storage-encrypted \
--region us-east-1
Create with a customer-managed KMS key:
aws docdb create-db-cluster \
--db-cluster-identifier my-encrypted-docdb \
--engine docdb \
--master-username myuser \
--master-user-password mypassword123 \
--storage-encrypted \
--kms-key-id arn:aws:kms:us-east-1:<account-id>:key/<key-id> \
--region us-east-1
Add an instance to the cluster:
aws docdb create-db-instance \
--db-instance-identifier my-docdb-instance \
--db-instance-class db.r5.large \
--db-cluster-identifier my-encrypted-docdb \
--engine docdb \
--region us-east-1
Encrypt an existing cluster via snapshot restore:
# Step 1: Create a snapshot of the unencrypted cluster
aws docdb create-db-cluster-snapshot \
--db-cluster-identifier my-unencrypted-cluster \
--db-cluster-snapshot-identifier my-snapshot \
--region us-east-1
# Step 2: Wait for snapshot to be available
aws docdb wait db-cluster-snapshot-available \
--db-cluster-snapshot-identifier my-snapshot \
--region us-east-1
# Step 3: Restore snapshot with encryption enabled
aws docdb restore-db-cluster-from-snapshot \
--db-cluster-identifier my-new-encrypted-cluster \
--snapshot-identifier my-snapshot \
--engine docdb \
--kms-key-id arn:aws:kms:us-east-1:<account-id>:key/<key-id> \
--region us-east-1
Replace:
<account-id>with your 12-digit AWS account ID<key-id>with your KMS key IDmypassword123with a strong password
CloudFormation (optional)
AWSTemplateFormatVersion: '2010-09-09'
Description: Encrypted Amazon DocumentDB cluster
Parameters:
DBClusterIdentifier:
Type: String
Description: Identifier for the DocumentDB cluster
Default: my-encrypted-docdb
MasterUsername:
Type: String
Description: Master username for the cluster
NoEcho: true
MasterUserPassword:
Type: String
Description: Master password for the cluster
NoEcho: true
MinLength: 8
DBInstanceClass:
Type: String
Description: Instance class for DocumentDB instances
Default: db.r5.large
AllowedValues:
- db.r5.large
- db.r5.xlarge
- db.r5.2xlarge
- db.r5.4xlarge
UseCustomerManagedKey:
Type: String
Default: 'true'
AllowedValues:
- 'true'
- 'false'
Description: Use customer-managed KMS key (true) or AWS-managed key (false)
Conditions:
CreateKmsKey: !Equals [!Ref UseCustomerManagedKey, 'true']
Resources:
DocumentDBKmsKey:
Type: AWS::KMS::Key
Condition: CreateKmsKey
Properties:
Description: KMS key for DocumentDB cluster encryption
EnableKeyRotation: true
KeyPolicy:
Version: '2012-10-17'
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub 'arn:aws:iam::${AWS::AccountId}:root'
Action: 'kms:*'
Resource: '*'
- Sid: Allow DocumentDB Service
Effect: Allow
Principal:
Service: rds.amazonaws.com
Action:
- 'kms:Encrypt'
- 'kms:Decrypt'
- 'kms:ReEncrypt*'
- 'kms:GenerateDataKey*'
- 'kms:DescribeKey'
Resource: '*'
DocumentDBKmsKeyAlias:
Type: AWS::KMS::Alias
Condition: CreateKmsKey
Properties:
AliasName: !Sub 'alias/docdb-${DBClusterIdentifier}'
TargetKeyId: !Ref DocumentDBKmsKey
DocumentDBSubnetGroup:
Type: AWS::DocDB::DBSubnetGroup
Properties:
DBSubnetGroupDescription: Subnet group for DocumentDB cluster
SubnetIds:
- !Ref PrivateSubnet1
- !Ref PrivateSubnet2
Tags:
- Key: Name
Value: !Sub '${DBClusterIdentifier}-subnet-group'
DocumentDBCluster:
Type: AWS::DocDB::DBCluster
Properties:
DBClusterIdentifier: !Ref DBClusterIdentifier
MasterUsername: !Ref MasterUsername
MasterUserPassword: !Ref MasterUserPassword
DBSubnetGroupName: !Ref DocumentDBSubnetGroup
StorageEncrypted: true
KmsKeyId: !If
- CreateKmsKey
- !GetAtt DocumentDBKmsKey.Arn
- !Ref AWS::NoValue
DeletionProtection: true
Tags:
- Key: Name
Value: !Ref DBClusterIdentifier
DocumentDBInstance:
Type: AWS::DocDB::DBInstance
Properties:
DBClusterIdentifier: !Ref DocumentDBCluster
DBInstanceClass: !Ref DBInstanceClass
Tags:
- Key: Name
Value: !Sub '${DBClusterIdentifier}-instance-1'
# Note: You must provide your own VPC and subnet resources
# The following are placeholders - replace with your actual subnet IDs
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
# Replace with your VPC and CIDR configuration
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [1, !GetAZs '']
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Outputs:
ClusterEndpoint:
Description: DocumentDB cluster endpoint
Value: !GetAtt DocumentDBCluster.Endpoint
ClusterPort:
Description: DocumentDB cluster port
Value: !GetAtt DocumentDBCluster.Port
KmsKeyArn:
Condition: CreateKmsKey
Description: ARN of the KMS key used for encryption
Value: !GetAtt DocumentDBKmsKey.Arn
Deploy with:
aws cloudformation deploy \
--template-file documentdb-encrypted.yaml \
--stack-name encrypted-documentdb \
--parameter-overrides \
DBClusterIdentifier=my-encrypted-docdb \
MasterUsername=myuser \
MasterUserPassword=mypassword123 \
UseCustomerManagedKey=true \
--capabilities CAPABILITY_IAM \
--region us-east-1
Terraform (optional)
# variables.tf
variable "cluster_identifier" {
description = "Identifier for the DocumentDB cluster"
type = string
default = "my-encrypted-docdb"
}
variable "master_username" {
description = "Master username for the cluster"
type = string
sensitive = true
}
variable "master_password" {
description = "Master password for the cluster"
type = string
sensitive = true
}
variable "instance_class" {
description = "Instance class for DocumentDB instances"
type = string
default = "db.r5.large"
}
variable "use_customer_managed_key" {
description = "Use customer-managed KMS key instead of AWS-managed key"
type = bool
default = true
}
variable "subnet_ids" {
description = "List of subnet IDs for the DocumentDB subnet group"
type = list(string)
}
variable "vpc_security_group_ids" {
description = "List of VPC security group IDs"
type = list(string)
default = []
}
# main.tf
data "aws_caller_identity" "current" {}
resource "aws_kms_key" "docdb" {
count = var.use_customer_managed_key ? 1 : 0
description = "KMS key for DocumentDB cluster encryption"
deletion_window_in_days = 7
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow DocumentDB Service"
Effect = "Allow"
Principal = {
Service = "rds.amazonaws.com"
}
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
Resource = "*"
}
]
})
tags = {
Purpose = "DocumentDB encryption"
}
}
resource "aws_kms_alias" "docdb" {
count = var.use_customer_managed_key ? 1 : 0
name = "alias/docdb-${var.cluster_identifier}"
target_key_id = aws_kms_key.docdb[0].key_id
}
resource "aws_docdb_subnet_group" "main" {
name = "${var.cluster_identifier}-subnet-group"
subnet_ids = var.subnet_ids
tags = {
Name = "${var.cluster_identifier}-subnet-group"
}
}
resource "aws_docdb_cluster" "main" {
cluster_identifier = var.cluster_identifier
master_username = var.master_username
master_password = var.master_password
db_subnet_group_name = aws_docdb_subnet_group.main.name
vpc_security_group_ids = var.vpc_security_group_ids
storage_encrypted = true
kms_key_id = var.use_customer_managed_key ? aws_kms_key.docdb[0].arn : null
deletion_protection = true
skip_final_snapshot = false
final_snapshot_identifier = "${var.cluster_identifier}-final-snapshot"
tags = {
Name = var.cluster_identifier
}
}
resource "aws_docdb_cluster_instance" "main" {
identifier = "${var.cluster_identifier}-instance-1"
cluster_identifier = aws_docdb_cluster.main.id
instance_class = var.instance_class
tags = {
Name = "${var.cluster_identifier}-instance-1"
}
}
# outputs.tf
output "cluster_endpoint" {
description = "DocumentDB cluster endpoint"
value = aws_docdb_cluster.main.endpoint
}
output "cluster_port" {
description = "DocumentDB cluster port"
value = aws_docdb_cluster.main.port
}
output "cluster_arn" {
description = "ARN of the DocumentDB cluster"
value = aws_docdb_cluster.main.arn
}
output "kms_key_arn" {
description = "ARN of the KMS key (if customer-managed key enabled)"
value = var.use_customer_managed_key ? aws_kms_key.docdb[0].arn : null
}
Deploy with:
terraform init
terraform apply \
-var="cluster_identifier=my-encrypted-docdb" \
-var="master_username=myuser" \
-var="master_password=mypassword123" \
-var='subnet_ids=["subnet-abc123", "subnet-def456"]'
Verification
After creating your encrypted cluster, verify encryption is enabled:
- Open the Amazon DocumentDB console
- Click Clusters and select your cluster
- On the Configuration tab, confirm Encryption shows Enabled
- Verify the KMS key ARN is displayed
CLI verification
Check encryption status of all clusters:
aws docdb describe-db-clusters \
--query 'DBClusters[*].{ClusterID:DBClusterIdentifier,Encrypted:StorageEncrypted,KmsKey:KmsKeyId}' \
--output table \
--region us-east-1
Check a specific cluster:
aws docdb describe-db-clusters \
--db-cluster-identifier my-encrypted-docdb \
--query 'DBClusters[0].{ClusterID:DBClusterIdentifier,Encrypted:StorageEncrypted,KmsKey:KmsKeyId}' \
--region us-east-1
Expected output for an encrypted cluster:
{
"ClusterID": "my-encrypted-docdb",
"Encrypted": true,
"KmsKey": "arn:aws:kms:us-east-1:123456789012:key/..."
}
Re-run the Prowler check:
prowler aws --checks documentdb_cluster_storage_encrypted
Additional Resources
- Amazon DocumentDB Encryption at Rest
- AWS KMS Key Management
- Amazon DocumentDB Best Practices
- AWS CLI DocumentDB Reference
Notes
-
Encryption cannot be changed after creation: Unlike many AWS resources, you cannot enable or disable encryption on an existing DocumentDB cluster. You must create a new cluster or restore from a snapshot with encryption enabled.
-
AWS Console vs CLI defaults: The AWS Console enables encryption by default, but the AWS CLI does not. Always specify
--storage-encryptedwhen using the CLI. -
KMS key cannot be changed: Once a cluster is created with a specific KMS key, that key is fixed for the cluster's lifetime. Plan your key strategy before creating clusters.
-
KMS key access is critical: If DocumentDB loses access to the KMS key (e.g., key is disabled or deleted), the cluster enters a terminal state. The only recovery is to restore from a backup. Always ensure your KMS key policies are correct.
-
Symmetric keys only: DocumentDB requires symmetric KMS keys. Asymmetric keys are not supported for encryption at rest.
-
AWS-managed vs customer-managed keys: The default AWS-managed key (
aws/rds) is simpler but offers less control. Customer-managed keys allow custom rotation policies, cross-account access, and fine-grained permissions. -
Backup retention: Backups are retained for at least 1 day by default. This is your safety net if KMS key access is lost.
-
Performance impact: Encryption has minimal performance impact due to efficient caching of data keys in memory.