I created a new S3 bucket, and left all defaults in place. I am trying to write an object to the bucket from a lambda function using the PutObject method. No matter what policies I attach or what I do, I get "access denied" on the action, unless I edit the bucket ACL and make it fully public. Obviously this isn't a very good solution. I really don't know what's going on: I know I've done this before without any special settings. The lambda and S3 bucket are both in the same account, and the role assigned to the lambda has the AWSLambdaFullAccess policy attached. I'm going crazy, any help would be appreciated.
5 Answers
Unfortunately "s3:PutObject" is not enough to make it running - you will keep getting 403 Access denied error.
You should add "s3:PutObjectAcl" policy to your Lambda role.
1 Comment
I was having this exact issue.
SOLUTION
The way I resolved it was with the policy below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PetsS3Write",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<bucket name or wildcard if you want all buckets writable>/*"
}
]
}
Comments
If you have a look at the actual policy in the IAM console you'll see this will give the lambda write access to the bucket AND any object. This is what it looks like in IAM view under the resources heading:
BucketName | string like | auth0-test-hucket, ObjectPath | string like | All.
Without the wildcard on the end it'll give no access to write any object to the bucket because it cannot name that object as there's no permission to do it. If you edit the policy you'll see you'll be able to specify the Bucket name and Object name.
So, I'm assuming the wildcard can be replaced with a string and it'll limited write access to that particular string. Like if you replaced the wildcard with "oneObject" then you'll only be able to create an object in the bucket named "oneObject". I've not tried this, but it seems to follow from the rules above.
Comments
Based on the permission sets you have assigned to your Lambda function, AWSLambdaFullAccess wont give you access to your S3 bucket. What you need in addition to those permissions is allowing access to S3. If PutObject is the only permission you need, then the following policy can be added to your Lambda role. Keep in mind, these permissions can be further locked down to the resource level but you can start with these:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1546988882992",
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
You can add or remove more S3 permissions based on your requirements.
5 Comments
*) for the "Resource" key, it's way to permissive. I had this exact same issue. My solution is below.I had this error and I know this is a strange answer but the root cause of my problem was that the encryption type had to be set.
In NodeJS, I had to do something like:
const filePath = path.join(__dirname, "../..", file);
const fileData = fs.readFileSync(filePath);
let result = await axios.put(s3Url, fileData, {
headers: {
"x-amz-server-side-encryption": "aws:kms:dsse",
"x-amz-server-side-encryption-aws-kms-key-id": "alias/MyS3KMSKey",
// Or this if you don't have a custom KMS key
// "x-amz-server-side-encryption-aws-kms-key-id":
// "alias/S3KMSMultiRegionKey",
},
});
Comments
You should change a policy for the s3 bucket. So you can use following code.
iamRoleStatements:
- Effect: 'Allow'
Action:
- 's3:PutObject'
- 's3:GetObject'
Resource: "arn:aws:s3:::*/*"
- Effect: 'Allow'
Action:
- 's3:ListBucket'
Resource: "arn:aws:s3:::*"
Note: you should put the s3:PutObjecct into Action.
Wish help for you.