What you'll learn
- Every Lambda function gets its own IAM role, with no permissions beyond writing its logs.
- Grant methods such as
table.grantReadData(fn)add a narrow policy for exactly one resource and the actions the method name promises. - Prefer the narrowest grant:
grantRead,grantPutorgrantReadDataovergrantReadWrite, and never wildcards.
Section 01
The wildcard trap
Hand-written policy statements are easy to get wrong in the generous direction. A function that only reads cards ends up able to delete the table, and a bug or a compromised dependency inherits all of it. Least privilege means giving each function exactly the actions it needs on exactly the resources it touches.
// Too broad: any DynamoDB or S3 action on anything
lookup.addToRolePolicy(new iam.PolicyStatement({
actions: ["dynamodb:*", "s3:*"],
resources: ["*"],
}));Section 02
Grants
Most L2 constructs that own data have grant methods. You pass the principal, which can be a function, a role or a user; CDK adds a statement to that principal's policy with the right actions and the resource's ARN. If the table has indexes, the grant also covers them.
| Method | Lets the function | Use for |
|---|---|---|
grantReadData | Read items from the table | Lookups |
grantWriteData | Write and delete items | Importers |
grantRead | Get and list objects | Serving cards |
grantPut | Put objects only | Uploaders |
grantReadWrite | Both directions | Only when it truly does both |
table.grantReadData(lookupFn); // GetItem, Query, Scan, BatchGetItem, …
bucket.grantRead(lookupFn); // s3:GetObject*, s3:GetBucket*, s3:List*
bucket.grantPut(uploadFn); // s3:PutObject, s3:PutObjectLegalHold, … (no read)Section 03
Read the policy it wrote
Open the exercise output and find the AWS::IAM::Policy resources. The Resource lists are references to the table and bucket, not *. One detail looks odd the first time: a DynamoDB grant ends with Ref: AWS::NoValue in its resource list. CDK adds the table's indexes there when it has any; with no index the slot is empty, and CloudFormation drops it.
Practice
Your turn
Both functions were given every permission on every resource. Delete the wildcard policies and use grants instead: LookupFn reads the table and the card bucket (grantReadData and grantRead; no write access); UploadFn may only put objects (grantPut) into the bucket and must not read them or touch the table.
addToRolePolicy; use table.grantReadData, bucket.grantRead for the lookup and bucket.grantPut for the upload.The simulator runs the constructs this course teaches, plus simple loops and helper methods. Other CDK code may not be recognised.
Check
Check your understanding
Quick Quiz · one question, as many tries as you need.
UploadFn only has to store card images in the bucket. Which grant fits?Choose one answer.