DynamoDB Security: IAM Fine-Grained Access, KMS and VPC Endpoints
Security is not a bolt-on after the app works. Dubai SaaS lead Layla Hassan and Pune bank engineer Arjun Mehta both said: We shipped CartLite, then a leaked key read every tenant. IAM LeadingKeys, KMS CMK, and a VPC endpoint would have blocked that blast. Builds on multi-tenant keys and modeling.
What you'll learn in this chapter
- Explain IAM least privilege for DynamoDB tables and indexes
- Use LeadingKeys / fine-grained access for tenant isolation
- Choose AWS-owned vs customer managed KMS keys
- Put DynamoDB behind a VPC gateway endpoint
- Run a safe lab and cleanup
1. Everyday example: hotel key cards
A master key opens every room — that is a wild IAM * on DynamoDB. A guest card opens one room — that is LeadingKeys on TENANT#acme. The lock cylinder is KMS. The private lift that never goes through the lobby is a VPC endpoint. Meera Joshi (Pune clinic) gives each ward app a card for PATIENT#wardA only.
2. Vertical steps
3. Why do we need this?
Why do we need this?
Stolen access keys, over-broad roles, and public network paths turn a good table into a data leak. Fine-grained IAM stops cross-tenant reads. KMS controls who can decrypt. VPC endpoints keep traffic off the public internet. Without these, modeling and transactions still leak.
4. What is it?
What is it?
IAM: identity policies on roles/users for dynamodb:GetItem, Query, PutItem, and index ARNs. Fine-grained access: condition keys like dynamodb:LeadingKeys so PK must start with a tenant prefix. KMS: SSE-DynamoDB (AWS owned) or SSE-KMS with your CMK. VPC gateway endpoint: private route from VPC to DynamoDB without NAT/IGW.
5. How to do it (step by step)
How to do it (step by step)
- List who reads/writes which table and GSI — no * unless break-glass.
- Scope Resource to table ARN and /index/* you need.
- For multi-tenant: add StringLike dynamodb:LeadingKeys TENANT#id.
- Enable encryption: default AWS owned, or CMK when you need key policy + rotation proof.
- Create vpc endpoint dynamodb gateway; update route tables.
- Deny dynamodb: via public path in SCPs if your org requires private only.
- Test with a second role that should fail cross-tenant GetItem.
6. IAM policy sketch (LeadingKeys)
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem","dynamodb:Query","dynamodb:PutItem","dynamodb:UpdateItem"],
"Resource": [
"arn:aws:dynamodb:ap-south-1:111122223333:table/lab-ddr-secure",
"arn:aws:dynamodb:ap-south-1:111122223333:table/lab-ddr-secure/index/*"
],
"Condition": {
"ForAllValues:StringLike": {"dynamodb:LeadingKeys": ["TENANT#acme"]}
}
}
# Meaning: role may only touch items whose PK begins with TENANT#acme.
Pair with app code that always prefixes PK. UI filters are not security — IAM is.
7. KMS and encryption at rest
- SSE-DynamoDB (default): AWS owns the key; simplest.
- SSE-KMS CMK: you own key policy, rotation, CloudTrail on Decrypt.
- Encrypts table, LSI, GSI, streams, backups at rest.
- In-transit: HTTPS/TLS to the DynamoDB API (and PrivateLink/endpoint path).
8. VPC gateway endpoint
Gateway endpoint for com.amazonaws.region.dynamodb adds a prefix list route. No security group on gateway endpoints — use endpoint policy to limit which principals/tables. Apps in private subnets reach DynamoDB without a NAT gateway for that traffic.
9. Commands with output and meaning
aws dynamodb create-table --table-name lab-ddr-secure --attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S --key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE --billing-mode PAY_PER_REQUEST --sse-specification Enabled=true,SSEType=KMS
# Output: TableStatus CREATING; SSEDescription present when active
aws dynamodb describe-table --table-name lab-ddr-secure --query 'Table.SSEDescription'
# Output: Status ENABLED, SSEType KMS — meaning encryption at rest on
aws ec2 create-vpc-endpoint --vpc-id vpc-0abc --service-name com.amazonaws.ap-south-1.dynamodb --route-table-ids rtb-0xyz --vpc-endpoint-type Gateway
# Output: VpcEndpointId vpce-… State available — private path ready
create-table with SSE KMS turns encryption on. describe proves it. create-vpc-endpoint makes the private route. Always delete lab tables and endpoints after practice.
10. Industry stories
- SaaS (Layla Hassan, Dubai): LeadingKeys per tenant role; stolen token cannot read other tenants.
- Bank (Arjun Mehta, Pune): CMK + key policy only payment role Decrypt; CloudTrail on misuse.
- Health (Meera Joshi): ward roles LeadingKeys PATIENT#wardX; VPC endpoint only.
- Retail (Diego Alvarez): separate IAM for batch export role vs online API role.
- IoT (Mei Lin): device writer role PutItem only; no Scan.
- Gaming (Carlos Rivera): score writer vs admin reader different policies.
11. Lab
How to do it (step by step)
- Create lab-ddr-secure on-demand with SSE KMS (AWS managed key ok for lab).
- Put TENANT#acme / ITEM#1 and TENANT#beta / ITEM#1.
- Attach a role with LeadingKeys TENANT#acme; confirm beta GetItem fails.
- Optional: create DynamoDB gateway endpoint in a lab VPC.
- Delete table (and endpoint if created).
Cleanup (stop billing)
- Delete lab-ddr-secure.
- Delete lab VPC endpoint if you made one.
- Confirm describe-table fails (ResourceNotFound).
12. Ops checklist before you ship
- Confirm TTL attribute name and units (epoch seconds).
- Decide soft-delete vs hard-delete vs archive-to-S3.
- Enable PITR on any table you cannot rebuild from source.
- Document RPO/RTO and who runs restore drills.
- If multi-region: pick write stickiness and conflict rules.
- If DAX: prove cache-miss path and warm-up plan.
- Tag Owner + Expiry on every lab resource.
- Budget alert in the account before load tests.
13. Copy-paste DynamoDB CLI starters (batch 2)
export AWS_DEFAULT_REGION=ap-south-1
# TTL status
aws dynamodb describe-time-to-live --table-name ShopApp
# PITR / continuous backups
aws dynamodb describe-continuous-backups --table-name ShopApp
# On-demand backup
aws dynamodb create-backup --table-name ShopApp --backup-name lab-shop-$(date +%Y%m%d)
# List backups
aws dynamodb list-backups --table-name ShopApp
# Global table description (v2)
aws dynamodb describe-table --table-name ShopApp --query 'Table.Replicas'
14. More industry stories
- Retail (Aisha Khan, Dubai): TTL clears abandoned carts; soft-delete keeps 30-day undo.
- Bank (Lucas Meyer, Berlin): PITR on ledger table; restore drill every quarter.
- Travel (Omar Haddad, Amman): Global Tables for catalog reads; inventory writes sticky.
- Gaming (Carlos Rivera, Mexico City): DAX for hot profile Gets; never cache money ledgers.
- Social (Priya Nair, Kochi): adjacency edges for follows; sparse GSI for unread inbox.
- IoT (Mei Lin, Shenzhen): device#day PK + TTL 14 days; rollups to S3.
15. Glossary (batch 2)
| Term | Meaning |
|---|---|
| TTL | Time to Live — attribute with epoch seconds; DynamoDB deletes later |
| Soft delete | Flag deleted=true; item remains until TTL/archive |
| PITR | Point-in-time recovery — continuous backups window |
| Global Table | Multi-region replicated DynamoDB table |
| LWW | Last-writer-wins conflict resolution on replicas |
| DAX | DynamoDB Accelerator — in-memory cache cluster |
| Adjacency list | Edge items modeling relationships in one table |
| Fan-out | Write once; push copies to many feeds/inboxes |
16. Practice: explain out loud
- 60s: TTL vs soft-delete vs S3 archive.
- 60s: PITR vs on-demand backup.
- 60s: when Global Tables help and hurt.
- 60s: DAX consistency trade-off.
- 60s: CartLite checkout keys in one breath.
- 60s: follow edge vs feed item.
- Record once; cut filler; record again.
17. Safe lab hygiene
- Use ap-south-1 labs with a budget alert.
- Prefix lab tables with lab- and your initials.
- Delete replicas, DAX clusters, and backups you created for labs.
- Never enable Global Tables on production without a write plan.
- Tag every resource Owner + Expiry.
- Export/import labs can create large S3 bills — delete prefixes.
18. How this set links other chapters
- Data modeling — keys we reuse in projects.
- Transactions — checkout and seat patterns.
- Streams + Lambda — fan-out and CDC.
- CRUD survey — short TTL note we deepen.
- What Is DynamoDB? — intro.
19. Delete / archive decision pad
| Need | Prefer | Why |
|---|---|---|
| Undo 7-30 days | Soft-delete flag | User restore |
| Hard expiry, no read | TTL attribute | Auto delete later |
| Compliance keep cold | Export/archive to S3 | Cheap long store |
| Mistake recovery | PITR / backup | Table-level restore |
20. Ten oral drill questions
- What units does DynamoDB TTL use?
- Does TTL delete instantly?
- PITR window typical length?
- Global Tables conflict default?
- When sticky writes matter?
- DAX vs API Gateway cache?
- Cart PK for a shopper?
- Order lines under which PK?
- Follow edge SK example?
- Unread inbox sparse GSI idea?
21. RPO / RTO mini workshop
- Write the worst data loss you can accept (RPO) in minutes.
- Write how long restore may take (RTO) before business pain.
- Map: on-demand backup vs PITR vs multi-region replica.
- Schedule a restore drill on a lab table this month.
- Name the person who runs the drill.
22. Cost watch list (batch 2)
- PITR storage and on-demand backup storage.
- Global Tables: replicated WCUs in every region.
- DAX node hours even at idle.
- Export to S3 + S3 storage + Athena later.
- Streams + Lambda still bill during TTL deletes.
23. Project Definition of Done
- Access patterns written and peer-reviewed.
- Sample items drawn for happy path + one failure.
- Lab table created, exercised, deleted (or tagged Expiry).
- At least one conditional write or transaction exercised.
- Cleanup commands pasted in your notes.
- One interview answer recorded out loud.
24. Cross-links inside this batch
- TTL hygiene → Backup/PITR for “oops” recovery.
- Global Tables → sticky writes from capacity/hot lessons.
- DAX → only after Query shapes are correct.
- P1 CartLite reuses modeling + transactions.
- P2 Social reuses adjacency + Streams ideas.
25. Quick self-check (yes/no)
- I can explain TTL delay vs instant DeleteItem.
- I know when soft-delete beats hard delete.
- I can start PITR and say what restore costs in time.
- I can name one reason NOT to use Global Tables.
- I know DAX does not fix a bad partition key.
- I can sketch CartLite USER# and ORD# keys.
- I can sketch a follow edge item.
- I delete lab replicas/DAX/backups the same day.
26. Common errors and fixes
Each row is a real mistake students and juniors hit. Read the fix before you panic.
| Error / symptom | Fix |
|---|---|
| IAM Resource * on all tables | Scope table + index ARNs. |
| UI hide tenants only | LeadingKeys on IAM. |
| LeadingKeys wrong prefix | Match PK design exactly. |
| Forget /index/* ARN | Add index ARNs you Query. |
| CMK policy blocks DynamoDB service | Allow service via key policy. |
| Expect gateway endpoint to use SG | Use endpoint policy + routes. |
| Access key in mobile app | Use Cognito/temp creds. |
| Scan allowed on tenant role | Deny Scan for app roles. |
| No negative test | Prove cross-tenant fails. |
27. Troubleshooting checklist
- AccessDeniedException: check action, ARN, LeadingKeys.
- ValidationException on condition: PK must be single value string for LeadingKeys.
- SSE not showing: wait CREATING; re-describe.
- Endpoint created but still public: route table not associated.
- CMK AccessDenied on backup/export: grant key to that role too.
28. FAQ
Q. Should I always use a single table?
Often yes for related access patterns; not a religion. Separate tables are fine for unrelated domains or different capacity/security needs.
Q. Do I still need RDS?
Yes for heavy joins, multi-row SQL reports, and strong relational constraints. See the intro DynamoDB vs RDS chapter.
Q. Is Scan evil?
Scan is a tool for rare admin jobs and small tables. Design so hot paths use Query/GetItem.
Q. Where are Put/Get command details?
In the CRUD survey, CLI and SDK chapters — this deep set links them instead of copying.
Q. Is VPC endpoint required?
Strongly recommended for private subnets and compliance; public HTTPS with locked IAM still encrypts in transit but uses public service endpoints.
Q. LeadingKeys vs app filter?
Both — app for UX, IAM for enforcement.
Q. AWS owned key vs CMK?
CMK when you need key policy, rotation proof, or cross-account control.
Q. Does FGAC work on GSI?
LeadingKeys applies to table PK on the request; design GSI keys so tenant still cannot cross-query blindly — often keep tenant in GSI PK too.
Q. What does dynamodb:LeadingKeys enforce?
The partition key value on the request must match the condition (often a tenant prefix).
Q. Why prefer a VPC gateway endpoint?
Private route to DynamoDB without NAT for that traffic; pair with endpoint policy.
Q. Name one CMK benefit over AWS-owned.
Key policy, CloudTrail Decrypt, rotation ownership.
Q. MNC: how do you prove tenant isolation?
Negative IAM test: role A cannot GetItem tenant B; show CloudTrail.
Try at home
- Write an IAM policy for one table + one GSI with LeadingKeys.
- Sketch who needs CMK Decrypt in your app.
- List route tables that need the DynamoDB endpoint.
In short
- Least privilege on table and index ARNs.
- LeadingKeys for tenant PK prefixes.
- KMS: default or CMK when you need control.
- VPC gateway endpoint for private path.
- Always negative-test cross-tenant access.
Revision, interview and comparison cards
Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.








More cards: Ravi Sir's Cards.
Practice Tasks
Maple Leaf Books is a bookselling business in Toronto. Emily Tremblay looks after its IT and cloud work. They count money in CAD and run their AWS resources in the ca-central-1 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.
0 / 16
Easy Least privilege ARNs — 1
Why: IAM.
What to do: Enter 1 if policies scope table and index ARNs.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy LeadingKeys FGAC — 1
Why: FGAC.
What to do: Enter 1 if dynamodb:LeadingKeys enforces PK prefixes.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy UI filter not enough — 1
Why: Truth.
What to do: Enter 1 if UI tenant filters alone are not security.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy CMK for key policy — 1
Why: KMS.
What to do: Enter 1 if CMK gives key policy and Decrypt audit.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy Describe secure table
Why: CLI.
What to do: Describe table ShopApp
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Easy LeadingKeys YAML
Why: Name.
What to do: YAML: condition_key: dynamodb:LeadingKeys.
- Start from the top-level keys the task names.
- Indent child keys with 2 spaces (no tabs).
- Fill in each property with the value from the task.
- Click Check answer. Key order does not matter.
Easy Endpoint policy limits — 1
Why: Policy.
What to do: Enter 1 if VPC endpoint policies can limit principals/tables.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium SSE encrypts at rest — 1
Why: Rest.
What to do: Enter 1 if SSE encrypts table indexes streams backups at rest.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Gateway VPC endpoint — 1
Why: Private.
What to do: Enter 1 if DynamoDB uses a gateway VPC endpoint.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Endpoint needs routes — 1
Why: Net.
What to do: Enter 1 if gateway endpoints need route table associations.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Include /index/* ARN — 1
Why: GSI.
What to do: Enter 1 if Query on GSI needs /index/* in Resource.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Tenant PK YAML
Why: Sketch.
What to do: YAML: pk: TENANT#acme, sk: ITEM#1.
- Start from the top-level keys the task names.
- Indent child keys with 2 spaces (no tabs).
- Fill in each property with the value from the task.
- Click Check answer. Key order does not matter.
Hard Negative cross-tenant test — 1
Why: Proof.
What to do: Enter 1 if you must prove cross-tenant GetItem fails.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Deny Scan on app roles — 1
Why: Anti.
What to do: Enter 1 if app roles should deny Scan.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard No access key in app — 1
Why: Creds.
What to do: Enter 1 if mobile apps must not embed long-lived access keys.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Delete lab same day — 1
Why: Hygiene.
What to do: Enter 1 if lab-ddr-secure should be deleted same day.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.