I'm trying to generate presigned URLs to upload objects to an S3 bucket but whenever I execute the PUT requests to the presigned URLs, I get 'Access Denied' errors. This is the code I am using to generate the URLs (runs inside a node lambda function):
app.post('/upload', async (req, res) => {
const filename = `${uuid()}.jpg`;
const url = s3.getSignedUrl('putObject', {
Bucket: BucketName,
Key: filename,
Expires: 3600,
ContentType: 'image/jpeg',
ACL: 'public-read',
});
res.status(200).json({ url, filename });
});
And here are the permissions from my serverless.yml
file:
service: my-service
provider:
name: aws
runtime: nodejs12.x
profile: my-profile
region: eu-west-2
iamRoleStatements:
- Effect: 'Allow'
Action:
- 's3:PutObject'
- 's3:PutObjectAcl'
Resource:
- !GetAtt galleryBucket.Arn
CodePudding user response:
I was applying the PutObject
and PutObjectAcl
permissions to the galleryBucket
instead of the objects within it.
You must apply the PutObject
permission to the objects inside the bucket, not the bucket itself
I updated my permissions to this and the PUT requests succeeded:
service: my-service
provider:
name: aws
runtime: nodejs12.x
profile: my-profile
region: eu-west-2
iamRoleStatements:
- Effect: 'Allow'
Action:
- 's3:PutObject'
- 's3:PutObjectAcl'
Resource:
Fn::Join: ['', ['arn:aws:s3:::', !Ref galleryBucket, '/*']]
Note the /*
at the end of the resource identifier