update docs

This commit is contained in:
2026-05-11 20:13:11 -03:00
commit 2ffabb672e
40 changed files with 5869 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
# IAM & Permissions
> Execution role vs resource policy. The two policies most people confuse.
## Two independent permission layers
Lambda has two separate permission surfaces that must each be correct independently. Confusing them is the most common "it works locally but not in AWS" failure.
| Layer | Question it answers | Who creates it |
|-------|---------------------|----------------|
| **Execution role** | What can *this Lambda function do* once running? (call S3, write to DynamoDB, publish to SNS…) | You — attached at function creation |
| **Resource policy** | Who is *allowed to invoke* this Lambda function? (API Gateway, another account, EventBridge…) | AWS adds it automatically for most triggers; you add it for cross-account or manual grants |
## Execution role
The execution role is an IAM role that Lambda assumes when running your function. Every Lambda must have one. The role's attached policies determine what AWS API calls the function can make. At minimum, every function needs:
```
# minimum: write its own logs
logs:CreateLogGroup
logs:CreateLogStream
logs:PutLogEvents
```
Common additions for a function that reads/writes S3:
```
s3:GetObject
s3:PutObject
s3:ListBucket # needed for paginator; often forgotten
kms:Decrypt # if the bucket uses a CMK, this is also required
```
The `AWSLambdaBasicExecutionRole` managed policy covers logs only — it is intentionally minimal. `AWSLambdaVPCAccessExecutionRole` adds the ENI permissions needed when the function is in a VPC.
## Resource policy
The resource policy is attached to the Lambda function itself (not an IAM identity). When you add an S3 event notification or API Gateway integration in the console, AWS automatically adds a resource policy entry allowing that service to invoke the function. For cross-account invocations you add this manually via `aws lambda add-permission`.
```bash
# grant another account permission to invoke
aws lambda add-permission \
--function-name my-function \
--principal 123456789012 \ # the other AWS account
--action lambda:InvokeFunction \
--statement-id cross-account-invoke
```
## Common mistakes
- **Missing `s3:ListBucket` on the bucket resource.** `ListObjectsV2` requires this on the *bucket ARN* (not the object ARN). Forgetting it causes AccessDenied on the paginator even when GetObject works fine.
- **Wrong resource ARN scope.** `s3:GetObject` must be on `arn:aws:s3:::bucket-name/*`; `s3:ListBucket` must be on `arn:aws:s3:::bucket-name`. Swapping them is a frequent typo.
- **CMK not in execution role.** KMS-encrypted bucket objects require both `s3:GetObject` and `kms:Decrypt`. The KMS key policy must also allow the role. Two separate policy documents, two separate denial points.
- **No resource policy for new trigger.** If you wire up EventBridge manually (not via the console), the trigger silently fails because there's no resource policy entry granting EventBridge `lambda:InvokeFunction`.
## Diagnosing permission errors
CloudTrail is the ground truth. Filter by `errorCode: "AccessDenied"` and `userIdentity.arn` matching the execution role ARN. The event tells you exactly which action on which resource was denied. CloudWatch will show the error in the Lambda log if you let the exception propagate, but CloudTrail shows it even when the call is made from a library that swallows the error.