DynamoDBSecurityDatabase

AWS DynamoDB Security: Access Control, Encryption, and Audit Logging

Vigilare Engineering

Platform Team · January 10, 2026 · 8 min read

DynamoDB's fully managed nature means you don't manage servers, OS patches, or database software — but it doesn't mean security is handled for you. Access control, encryption, audit logging, and network configuration are all your responsibility. DynamoDB's API-based access model creates specific security considerations that differ from traditional relational databases: access is controlled entirely through IAM rather than database-level users and passwords, and the access patterns are API calls rather than SQL queries.

Getting DynamoDB security right means understanding the IAM policy model, configuring appropriate conditions to limit access scope, and ensuring that access through public internet paths doesn't occur for sensitive data.

IAM Policy Design for DynamoDB

DynamoDB access control is entirely IAM-based — there are no database users or roles at the DynamoDB layer. Every application, Lambda function, EC2 instance role, and IAM user that needs DynamoDB access gets it through IAM policies.

Least-privilege DynamoDB policies specify the exact actions and table resources allowed:

{
  "Effect": "Allow",
  "Action": ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem"],
  "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/OrdersTable",
  "Condition": {
    "ForAllValues:StringEquals": {"dynamodb:LeadingKeys": ["${aws:PrincipalTag/UserId}"]}
  }
}

The dynamodb:LeadingKeys condition is particularly powerful for multi-tenant data stores. When the DynamoDB partition key includes the user ID or tenant ID, this condition restricts each IAM principal to only accessing items with their own ID as the partition key. A user with their UserID tag set to "user123" can only access DynamoDB items where the partition key is "user123" — they can't access other users' data even if their IAM policy technically allows the DynamoDB actions.

For read-only analytics or reporting access, create a separate IAM role with only dynamodb:Query and dynamodb:Scan (and specify which tables are queryable). Never give analytics access the write operations unless they actually need to write.

VPC Endpoints for DynamoDB

By default, DynamoDB API calls from EC2 instances and Lambda functions transit the public internet, even when originating from within your VPC. VPC endpoints for DynamoDB enable these calls to stay within the AWS network, never traversing the internet. This provides two benefits: improved security (data doesn't leave AWS's network) and reduced cost (no NAT gateway charges for DynamoDB traffic).

Create a Gateway VPC endpoint for DynamoDB in each VPC where workloads access DynamoDB:

aws ec2 create-vpc-endpoint   --vpc-id vpc-0123456789abcdef0   --service-name com.amazonaws.us-east-1.dynamodb   --route-table-ids rtb-0123456789abcdef0

Gateway endpoints add routes to your route tables pointing DynamoDB traffic to the endpoint rather than the internet gateway or NAT gateway. No application code changes are required — the endpoint is transparent to the application. Enabling VPC endpoints for DynamoDB typically saves significant NAT gateway charges for DynamoDB-heavy applications while simultaneously improving security.

Encryption Configuration

DynamoDB tables are encrypted at rest by default using AWS-owned KMS keys. For additional control and audit visibility, switch to customer-managed KMS keys (CMK):

aws dynamodb create-table   --table-name SensitiveDataTable   --sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=arn:aws:kms:us-east-1:123456789012:key/key-id   [... other options ...]

With CMK encryption, every DynamoDB operation that requires decryption generates a KMS API call visible in CloudTrail. This provides an additional audit trail: not just "who called the DynamoDB API" but "who used the encryption key to access the data." For compliance frameworks requiring encryption key audit trails, CMK encryption satisfies this requirement in a way that AWS-owned key encryption doesn't.

DynamoDB Streams and Access Logging

CloudTrail data events for DynamoDB log every GetItem, PutItem, DeleteItem, and UpdateItem API call at the item level. This is the most detailed audit logging available for DynamoDB but generates significant CloudTrail volume and cost for high-throughput tables. Enable data event logging selectively for tables containing sensitive data (PII, financial records, health data) and use management-level CloudTrail (enabled by default) for tables where item-level logging isn't needed.

Configure CloudTrail data events for specific tables:

aws cloudtrail put-event-selectors   --trail-name your-trail-name   --event-selectors '[{
    "ReadWriteType": "All",
    "IncludeManagementEvents": false,
    "DataResources": [{
      "Type": "AWS::DynamoDB::Table",
      "Values": ["arn:aws:dynamodb:us-east-1:123456789012:table/SensitiveTable"]
    }]
  }]'

Point-in-Time Recovery and Backups

Enable point-in-time recovery (PITR) for all production DynamoDB tables. PITR provides continuous backups with 35-day recovery window, protecting against accidental deletion or corruption. PITR is not enabled by default — configure it explicitly or enforce it with an AWS Config rule.

For compliance frameworks requiring backup evidence, export PITR backup status from AWS Config or use the DynamoDB DescribeTable API to verify PITR is enabled. Create an AWS Config custom rule that alerts when PITR is disabled on tables with specific tags (e.g., DataClassification: Sensitive).

Related Reading

FAQ

Can DynamoDB resource policies restrict access?

Yes. DynamoDB tables support resource-based policies that control cross-account access and can add conditions that IAM policies alone can't enforce. Resource policies are evaluated in addition to IAM policies for same-account access. For multi-tenant scenarios, combining IAM conditions (like LeadingKeys) with resource policies provides defense in depth for data isolation.

How do I audit who accessed specific DynamoDB items?

Enable CloudTrail data events for the table. Each item-level API call (GetItem, Query, Scan, etc.) generates a CloudTrail event that includes the requesting principal, the table name, and (for GetItem) the specific key being accessed. Note that Scan operations don't log the specific items returned — just the scan itself. For fine-grained item access auditing, Query and GetItem calls provide better attribution than Scan.

Does DynamoDB support database-level access controls like PostgreSQL row-level security?

DynamoDB doesn't have native row-level security equivalent to PostgreSQL. The IAM LeadingKeys condition provides partition-key-level access restriction, but not arbitrary attribute-based conditions. For more complex data isolation requirements (restricting access based on non-partition-key attributes), implement access control in your application layer before calling DynamoDB, rather than relying solely on IAM conditions.

Protect your AWS accounts before it's too late

Vigilare monitors your AWS accounts for suspension risks — billing anomalies, IAM issues, GuardDuty findings, and more — and alerts you before AWS takes action.

Written by Vigilare Engineering

Platform Team