If the permissions between a Lambda function and an Amazon S3 bucket are incomplete or incorrect, then Lambda returns an Access Denied error.
If you're getting Access Denied errors on public read requests that are allowed, check the bucket's Amazon S3 Block Public Access settings. Review the S3 Block Public Access settings at both the account and bucket level. These settings can override permissions that allow public read access.
Short description. The "403 Access Denied" error can occur due to the following reasons: Your AWS Identity and Access Management (IAM) user or role doesn't have permissions for both s3:GetBucketPolicy and s3:PutBucketPolicy.
Your Lambda does not have privileges (S3:GetObject)
.
Go to IAM dashboard, check the role associated with your Lambda execution. If you use AWS wizard, it automatically creates a role called oneClick_lambda_s3_exec_role
. Click on Show Policy
. It should show something similar to the attached image. Make sure S3:GetObject
is listed.
Interestingly enough, AWS returns 403 (access denied) when the file does not exist. Be sure the target file is in the S3 bucket.
If you are specifying the Resource don't forget to add the sub folder specification as well. Like this:
"Resource": [
"arn:aws:s3:::BUCKET-NAME",
"arn:aws:s3:::BUCKET-NAME/*"
]
I ran into this issue and after hours of IAM policy madness, the solution was to:
Done. Your carefully written IAM role policies don't matter, neither do specific bucket policies (I've written those too to make it work). Or they just don't work on my account, who knows.
[EDIT]
After a lot of tinkering the above approach is not the best. Try this:
{ "Version": "2012-10-17", "Id": "Lambda access bucket policy", "Statement": [ { "Sid": "All on objects in bucket lambda", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AWSACCOUNTID:root" }, "Action": "s3:*", "Resource": "arn:aws:s3:::BUCKET-NAME/*" }, { "Sid": "All on bucket by lambda", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AWSACCOUNTID:root" }, "Action": "s3:*", "Resource": "arn:aws:s3:::BUCKET-NAME" } ] }
Worked for me and does not require for you to share with all authenticated AWS users (which most of the time is not ideal).
If you have encryption set on your S3 bucket (such as AWS KMS), you may need to make sure the IAM role applied to your Lambda function is added to the list of IAM > Encryption keys > region > key > Key Users for the corresponding key that you used to encrypt your S3 bucket at rest.
In my screenshot, for example, I added the CyclopsApplicationLambdaRole role that I have applied to my Lambda function as a Key User in IAM for the same AWS KMS key that I used to encrypt my S3 bucket. Don't forget to select the correct region for your key when you open up the Encryption keys UI.
Find the execution role you've applied to your Lambda function:
Find the key you used to add encryption to your S3 bucket:
In IAM > Encryption keys, choose your region and click on the key name:
Add the role as a Key User in IAM Encryption keys for the key specified in S3:
If all the other policy ducks are in a row, S3 will still return an Access Denied message if the object doesn't exist AND the requester doesn't have ListBucket permission on the bucket.
From https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html:
...If the object you request does not exist, the error Amazon S3 returns depends on whether you also have the s3:ListBucket permission.
If you have the s3:ListBucket permission on the bucket, Amazon S3 will return an HTTP status code 404 ("no such key") error. if you don’t have the s3:ListBucket permission, Amazon S3 will return an HTTP status code 403 ("access denied") error.
I too ran into this issue, I fixed this by providing s3:GetObject*
in the ACL as it is attempting to obtain a version of that object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With