Reputation: 910
I have the following policy on an S3 bucket created with the AWS policy generator to allow a lambda, running with a specific role, access to the files in the bucket. However, when I execute the Lambda, I get 403 permission denied:
"errorMessage": "Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: <requestId>)",
"errorType": "com.amazonaws.services.s3.model.AmazonS3Exception",
The Policy on the S3 bucket:
{
"Version": "2012-10-17",
"Id": "Policy<number>",
"Statement": [
{
"Sid": "Stmt<number>",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account>:role/<roleName>"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::<bucketName>/*"
}
]
}
What is wrong with the policy? The Lamba is running with the role configured in the policy.
Upvotes: 38
Views: 65728
Reputation: 1
When you face an 'Access Denied' issue for a bucket, make sure you have added the necessary policy to the IAM role (AWS Access Key & AWS Secret Key) that you are using to interact with it.
Example: Your bucket name: saporacle Go to IAM dashboard, select your user --> Add Permission --> Select attach policies directly --> Search S3 --> Add
Upvotes: 0
Reputation: 2360
I faced a similar issue and tried many different bucket policies and most of them either failed to do the job (got Access Denied as explained in the question) or needed me to go extra mile and add some bits and pieces. Below is the simplest way to get it working without having to add any new resource or define a new role for your Lambda.
You just need to find your Lambda execution role from AWS console:
Let's assume the role name is 'MyLambdaRoleName-1234' Then find the role id using AWS CLI or AWS CloudShell:
aws iam get-role --role-name MyLambdaRoleName-1234
you will find the role id from the result:
Copy the RoleId and use it in below bucket policy. Let's assume it is 'ARARARARARARARARARARA'
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "Deny everything for any service but Lambda",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:*"
],
"Resource": "arn:aws:s3:::<bucketName>/*",
"Condition": {
"StringNotLike": {
"aws:userId": [
"ARARARARARARARARARARA:*",
"ARARARARARARARARARARA"
]
}
}
}
]
}
I wanted to allow only my Lambda to perform actions on the bucket and stop any other role/services to run any action. If this is not your case and you just want to add a policy to give access to your Lambda, of course you just need to replace Deny
with Allow
and StringNotLike
with StringLike
.
Upvotes: 0
Reputation: 269284
A role assigned to an AWS Lambda function should be created with an AWS Lambda role (that is selected when creating a Role in the IAM console).
Roles do not have a Principal since the permissions are assigned to whichever service (in this case, Lambda function) is using the role.
Also, you should assign permissions on the bucket itself (e.g. to list contents) and on the contents of the bucket (e.g. to GetObject).
It would be something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123XXX:role/service-role/LAMBDA_ROLE_NAME"
},
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
Upvotes: 47
Reputation: 1730
After looping for I while i could make it work, the process is:
IAM Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt*******",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging",
"s3:PutObjectVersionAcl",
"s3:PutObjectVersionTagging"
],
"Resource": [
"arn:aws:s3:::<bucket-name>"
]
}
]
}
and I use this policy on the s3 Bucket
{
"Id": "Policy************",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt********",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectTagging",
"s3:PutObjectVersionAcl",
"s3:PutObjectVersionTagging"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::<bucket-name>/*",
"Principal": {
"AWS": [
"arn:aws:iam::*********:role/<lambda-function-name>"
]
}
}
]
}
Upvotes: 16