DynamoDB tables should have encryption enabled
DynamoDB tables frequently store application state, user profiles, session tokens, and other sensitive records. While AWS enabled default encryption with AWS-owned keys for all new tables created after November 2018, several compliance frameworks require explicit use of AWS managed or customer managed KMS keys to demonstrate control over key lifecycle, rotation, and access policies.
Without explicit encryption configuration, you lose the ability to audit key usage through CloudTrail, enforce key rotation schedules, or revoke access by disabling a key. Customer managed keys give you granular IAM-level control over which principals can decrypt table data, something AWS-owned keys cannot provide.
Retrofit consideration
Switching from AWS-owned to AWS managed or customer managed KMS keys triggers a full table re-encryption. For large tables, this consumes additional read/write capacity and can take significant time.
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 "dynamodb_table" {
source = "pcidss.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
module "dynamodb_table" {
source = "hipaa.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
module "dynamodb_table" {
source = "gdpr.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
module "dynamodb_table" {
source = "eugmpannex11.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
module "dynamodb_table" {
source = "hipaasecurity2003.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
module "dynamodb_table" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
module "dynamodb_table" {
source = "pcidssv321.compliance.tf/terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
}
If you use terraform-aws-modules/dynamodb-table/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 "dynamodb_table" {
source = "terraform-aws-modules/dynamodb-table/aws"
version = ">=5.0.0"
attributes = [
{
name = "id"
type = "S"
}
]
hash_key = "id"
name = "abc123"
server_side_encryption_enabled = true
}
Use AWS provider resources directly. See docs for the resources involved: aws_dynamodb_table.
resource "aws_dynamodb_table" "this" {
attribute {
name = "id"
type = "S"
}
billing_mode = "PAY_PER_REQUEST"
hash_key = "id"
name = "pofix-abc123"
server_side_encryption {
enabled = true
}
}
What this control checks
The control validates that aws_dynamodb_table includes a server_side_encryption block with enabled = true. With enabled = true but no kms_key_arn, DynamoDB uses the AWS managed key (alias/aws/dynamodb). To use a customer managed key, set kms_key_arn to the ARN of an aws_kms_key resource. Omitting the block entirely leaves the table on AWS-owned encryption, which most compliance controls flag as a failure since there is no explicit, auditable encryption configuration.
Common pitfalls
AWS-owned encryption may still fail the control
All DynamoDB tables created after November 2018 use AWS-owned encryption by default, but omitting the
server_side_encryptionblock inaws_dynamodb_tablemeans Terraform sends no explicit encryption configuration. Most compliance controls requireenabled = trueto register a pass, even though the data is technically encrypted.Global table replicas need per-region KMS keys
When using
replicablocks withinaws_dynamodb_table, each replica accepts its ownkms_key_arn. Specifying a customer managed key for the primary but omitting it for replicas leaves those replicas on default key settings in their regions, creating an inconsistent compliance posture that is easy to miss until an auditor checks each region independently.Customer managed key deletion makes data permanently inaccessible
Schedule an
aws_kms_keyfor deletion and let the waiting period expire, and DynamoDB can no longer decrypt the table. There is no recovery path. Usedeletion_window_in_dayswith a long window, and setenable_key_rotation = trueto avoid the manual rotation pressure that pushes teams toward risky key replacements.Terraform plan shows replacement when switching encryption types
Changing
kms_key_arnfrom one customer managed key to another, or toggling between AWS managed and customer managed, triggers an in-place update that re-encrypts the table. On-demand tables handle this transparently, but provisioned tables may experience throttling if throughput is already constrained. Plan the switch during a low-traffic window.
Audit evidence
Auditors expect AWS Config rule evaluation results (such as the managed rule dynamodb-table-encrypted-kms) returning COMPLIANT for each DynamoDB table in scope. The DynamoDB console's "Additional settings" tab displays the encryption type (AWS owned, AWS managed, or customer managed) and the associated KMS key ARN where applicable.
For customer managed keys, CloudTrail logs showing kms:Decrypt and kms:GenerateDataKey calls tied to the DynamoDB table ARN demonstrate active key usage. KMS key policies, key rotation status, and alias configurations provide further evidence of encryption governance. Security Hub consolidates findings across all tables and can produce a single-report view for the auditor.
Framework-specific interpretation
PCI DSS v4.0: Requirements 3.4 and 3.5 call for rendering stored PAN unreadable and protecting the keys used to do it. Enabling DynamoDB encryption with an auditable KMS key supports both requirements for cardholder data stored in the table.
HIPAA Omnibus Rule 2013: HIPAA treats encryption of ePHI at rest as an addressable implementation specification under 45 CFR 164.312(a)(2)(iv). Tables storing ePHI should use documented, risk-based encryption. Customer managed KMS keys improve on the default by making every decrypt operation visible in CloudTrail, which satisfies the auditability expectation that AWS-owned keys cannot meet.
GDPR: Article 32 calls for appropriate technical measures to secure personal data processing. For DynamoDB tables holding personal data of EU data subjects, encryption at rest with a customer managed key provides a concrete, verifiable measure that also reduces the impact of physical media compromise.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
dynamodb_table_encryption_enabledAWS Config Managed Rule:
DYNAMODB_TABLE_ENCRYPTION_ENABLEDCheckov Check:
CKV_AWS_119Powerpipe Control:
aws_compliance.control.dynamodb_table_encryption_enabledProwler Check:
dynamodb_tables_kms_cmk_encryption_enabledKICS Query:
ce089fd4-1406-47bd-8aad-c259772bb294Trivy Check:
AWS-0025
Last reviewed: 2026-03-09