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
