Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · DynamoDB

DynamoDB.1: DynamoDB tables should auto-scale capacity

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub DynamoDB.1 check?

DynamoDB.1 checks that a table scales its capacity automatically. It reports FAILED for a provisioned table that has no Application Auto Scaling on its read and write capacity, and passes tables in on-demand mode.

Why does DynamoDB.1 matter?

A static provisioned table is both a throttling risk and a cost trap: under-provision and requests get throttled during spikes, over-provision and you pay for idle capacity around the clock. Auto-scaling or on-demand mode keeps capacity tracking actual demand so neither failure mode bites.

How do I fix DynamoDB.1?

  1. Audit tables for capacity mode and any attached scaling policies.
  2. For spiky or unpredictable traffic, switch the table to on-demand capacity mode.
  3. For steady, predictable traffic, attach Application Auto Scaling to the table's read and write capacity with sensible target utilisation.
  4. Verify the policy is active and the control passes.

Remediation script · bash

# Decide the mode from real data, then apply it.
TABLE=sessions-prod

# 1. Pull average consumed write capacity over the last 14 days.
aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name ConsumedWriteCapacityUnits \
  --dimensions Name=TableName,Value=$TABLE \
  --start-time "$(date -u -d '14 days ago' +%FT%TZ)" \
  --end-time "$(date -u +%FT%TZ)" \
  --period 3600 --statistics Average Maximum

# 2a. Spiky / low-utilization table -> on-demand.
aws dynamodb update-table --table-name $TABLE --billing-mode PAY_PER_REQUEST

# 2b. OR steady high-volume table -> keep provisioned, add auto scaling
#     (see the register-scalable-target / put-scaling-policy calls earlier).

Full walkthrough (console steps, edge cases and verification) in the lesson Make DynamoDB tables scale capacity with demand.

Is DynamoDB.1 a false positive?

A flat, predictable workload deliberately pinned to fixed provisioned capacity is the legitimate fail. Some tables carry steady, well-understood traffic where a hand-tuned provisioned ceiling (often paired with a reserved-capacity purchase) is cheaper and more predictable than auto scaling, and the operator intends never to let it move, but the control reports FAILED because it only passes on-demand mode or provisioned mode with an attached Application Auto Scaling policy. There's also a timing false positive: right after you attach a scaling policy, the finding can lag until the next evaluation. If the fixed sizing is a real, owned decision, don't bolt on a no-op scaling policy to pass: suppress the finding (workflow status SUPPRESSED via BatchUpdateFindings or an automation rule keyed on a tag) with a note recording the capacity rationale and the reserved-capacity commitment.

  • DynamoDB.2 DynamoDB tables should have PITR
  • DynamoDB.3 DAX clusters should be encrypted at rest
  • DynamoDB.4 DynamoDB tables should be in a backup plan
  • DynamoDB.6 DynamoDB tables should have deletion protection
  • DynamoDB.7 DAX clusters should be encrypted in transit