This check flags Amazon DocumentDB clusters that were created without encryption at rest. Unencrypted storage exposes your database snapshots, backups, and underlying volumes to anyone who gains access to them. Encryption can only be enabled at cluster creation, so the fix is to create a new encrypted cluster with a KMS key and migrate your data.
Amazon DocumentDB is a managed document database that speaks the MongoDB API. It is a popular choice for teams that want MongoDB compatibility without running the database themselves. Like every managed datastore on AWS, it stores your data on EBS-backed volumes, takes automated snapshots, and replicates across availability zones. If that storage layer is not encrypted, every copy of your data sits on disk in plaintext.
The docdb_unencrypted check looks at each DocumentDB cluster in your account and reports any cluster where storage encryption is disabled. It is a straightforward boolean: either the cluster has a KMS key attached and encryption turned on, or it does not.
What this check detects
The check inspects the StorageEncrypted attribute on each DocumentDB cluster. When that attribute is false, the cluster fails the check. Encryption at rest in DocumentDB covers:
- The underlying cluster storage volumes
- Automated and manual snapshots
- Backups stored by the service
- Replica instances within the cluster
You can confirm the current state of a cluster with a quick CLI call:
aws docdb describe-db-clusters \
--query 'DBClusters[*].{Cluster:DBClusterIdentifier,Encrypted:StorageEncrypted,KmsKey:KmsKeyId}' \
--output table
Any row where Encrypted reads False is what this check is catching.
Note: DocumentDB uses AES-256 for encryption at rest. When enabled, encryption is handled transparently by the service, so your application code and queries do not change at all. There is no performance penalty worth measuring for most workloads.
Why it matters
Encryption at rest is the control that protects your data when the abstraction breaks down. The application talks to DocumentDB over a connection, but the bytes themselves live on physical disks managed by AWS. Encryption at rest defends against the scenarios where someone reaches those bytes through a path other than your application.
Snapshot exposure
The most common real-world risk is snapshot sprawl. DocumentDB snapshots inherit the encryption state of their source cluster. An unencrypted cluster produces unencrypted snapshots. Snapshots are easy to share across accounts and easy to copy to other regions. A single misconfigured sharing setting or an overly permissive IAM policy can put a plaintext copy of your entire database in front of an attacker, and they never need to touch the running cluster to read it.
Compliance failures
If you handle regulated data, encryption at rest is usually not optional. PCI DSS, HIPAA, SOC 2, and ISO 27001 all expect sensitive data to be encrypted at rest. An unencrypted cluster holding cardholder data or PHI is a finding that auditors will flag immediately, and remediation under audit pressure is far more stressful than getting it right up front.
Defense in depth
Encryption at rest does not replace network controls, IAM, or authentication. It sits underneath all of them as a final layer. If an attacker compromises an EBS snapshot, abuses a backup pipeline, or exploits a service-level flaw, encryption is what stands between them and readable data.
Warning: Encryption at rest does not protect data in transit or data that an authenticated client can read. It is one layer. You still need TLS enabled on the cluster (DocumentDB enables TLS by default) and tight IAM and security group rules.
How to fix it
Here is the catch that trips people up: you cannot enable encryption on an existing DocumentDB cluster. The StorageEncrypted flag is set at creation and is immutable for the life of the cluster. To remediate, you create a new encrypted cluster and move your data into it.
There are two practical paths depending on your downtime tolerance.
Option A: Restore from a snapshot (simplest, has downtime)
When you restore a snapshot, you can specify a KMS key, and the restored cluster will be encrypted even if the snapshot source was not. This is the cleanest way to flip an existing cluster to encrypted.
- Take a manual snapshot of the existing cluster.
- Restore that snapshot into a new cluster with a KMS key specified.
- Cut your application over to the new cluster endpoint.
- Verify, then delete the old cluster.
# 1. Create a manual snapshot of the unencrypted cluster
aws docdb create-db-cluster-snapshot \
--db-cluster-identifier my-docdb-cluster \
--db-cluster-snapshot-identifier my-docdb-snapshot
# Wait until the snapshot is available
aws docdb wait db-cluster-snapshot-available \
--db-cluster-snapshot-identifier my-docdb-snapshot
# 2. Restore into a NEW encrypted cluster
aws docdb restore-db-cluster-from-snapshot \
--db-cluster-identifier my-docdb-cluster-encrypted \
--snapshot-identifier my-docdb-snapshot \
--engine docdb \
--storage-encrypted \
--kms-key-id alias/docdb-encryption-key
The restore creates the cluster but not the instances. Add at least one instance so the cluster is usable:
aws docdb create-db-instance \
--db-instance-identifier my-docdb-encrypted-instance-1 \
--db-instance-class db.r6g.large \
--engine docdb \
--db-cluster-identifier my-docdb-cluster-encrypted
Warning: Restoring from a snapshot captures a point in time. Any writes that hit the old cluster after the snapshot was taken will not be present in the new cluster. Stop writes or put the application in maintenance mode before snapshotting if you cannot afford to lose those writes.
Option B: Live migration with mongodump/mongorestore (minimal downtime)
If you want to keep writes flowing as long as possible, dump the data and load it into a fresh encrypted cluster. Create the encrypted cluster first:
aws docdb create-db-cluster \
--db-cluster-identifier my-docdb-cluster-encrypted \
--engine docdb \
--master-username dbadmin \
--master-user-password 'CHANGE_ME' \
--storage-encrypted \
--kms-key-id alias/docdb-encryption-key
Then move the data:
# Dump from the source cluster
mongodump \
--uri "mongodb://dbadmin:pass@old-cluster-endpoint:27017/?tls=true&tlsCAFile=global-bundle.pem&retryWrites=false" \
--out ./docdb-dump
# Restore into the new encrypted cluster
mongorestore \
--uri "mongodb://dbadmin:pass@new-cluster-endpoint:27017/?tls=true&tlsCAFile=global-bundle.pem&retryWrites=false" \
./docdb-dump
Do a final short maintenance window to capture any deltas and switch the application endpoint.
Danger: Do not delete the old cluster until you have fully validated the new one against real traffic. Once a DocumentDB cluster and its snapshots are deleted, the data is gone. Keep the old cluster around for at least a few days as a fallback.
Fixing it in Terraform
If you manage DocumentDB with Terraform, the encrypted cluster looks like this. Note that changing storage_encrypted on an existing resource forces replacement, so plan the migration accordingly.
resource "aws_docdb_cluster" "main" {
cluster_identifier = "my-docdb-cluster-encrypted"
engine = "docdb"
master_username = "dbadmin"
master_password = var.master_password
storage_encrypted = true
kms_key_id = aws_kms_key.docdb.arn
backup_retention_period = 7
skip_final_snapshot = false
}
resource "aws_kms_key" "docdb" {
description = "KMS key for DocumentDB encryption at rest"
deletion_window_in_days = 30
enable_key_rotation = true
}
Tip: Use a customer-managed KMS key rather than the default AWS-managed key. A customer-managed key lets you control rotation, audit usage through CloudTrail, and revoke access by editing the key policy. It also makes cross-account snapshot sharing controllable, since the recipient account needs explicit grants on your key.
How to prevent it from happening again
Because encryption cannot be retrofitted, prevention is far cheaper than remediation. Block unencrypted clusters before they ever reach production.
Service Control Policy
An SCP at the organization level can deny the creation of unencrypted DocumentDB clusters across every account:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnencryptedDocDB",
"Effect": "Deny",
"Action": "rds:CreateDBCluster",
"Resource": "*",
"Condition": {
"Bool": {
"rds:StorageEncrypted": "false"
},
"StringEquals": {
"rds:DatabaseEngine": "docdb"
}
}
}
]
}
Note: DocumentDB shares the RDS API surface, which is why the SCP condition keys use the rds: prefix and not a separate docdb: namespace. The same applies to many CLI and IAM patterns for DocumentDB.
Policy-as-code in CI/CD
If you provision with Terraform, scan plans before apply. A Checkov or tfsec gate catches unencrypted clusters during code review, long before anyone runs terraform apply.
# Checkov against Terraform
checkov -d ./infra --check CKV_AWS_74
# tfsec against the same directory
tfsec ./infra
Wire this into your pipeline so a failing check blocks the merge:
# GitHub Actions step
- name: Scan Terraform
run: checkov -d ./infra --compact --quiet
Continuous detection
SCPs and CI gates cover the resources you create through approved paths. Continuous scanning covers everything else, including clusters created by hand during an incident or by a team that bypassed the pipeline. Lensix runs the docdb_unencrypted check on a schedule and surfaces any drift, so an unencrypted cluster cannot quietly live in your account for months.
Best practices
- Encrypt at creation, always. Treat
storage_encrypted = trueas a non-negotiable default in every module and template. The cost of retrofitting is a full migration. - Use customer-managed KMS keys. They give you rotation control, granular access policies, and a clean audit trail in CloudTrail.
- Enable automatic key rotation. Set
enable_key_rotation = trueso the key material rotates annually without any data re-encryption work on your part. - Lock down snapshot sharing. Audit which snapshots are shared and with whom. An encrypted snapshot shared cross-account still requires the recipient to have KMS grants, which is exactly the control you want.
- Pair encryption with TLS. DocumentDB enables TLS in transit by default. Keep it on, and require it in your connection strings so data is protected on the wire as well as at rest.
- Tighten access alongside encryption. Encryption is the last layer. Keep clusters in private subnets, restrict security groups to known application sources, and scope IAM tightly.
Encryption at rest for DocumentDB is one of those checks that is trivial to satisfy on day one and painful to fix later. Set the default, gate it in your pipeline, and let continuous scanning catch the strays.

