Home > Blockchain >  AWS S3 & Serverless - Access Denied when using PUT presigned URL
AWS S3 & Serverless - Access Denied when using PUT presigned URL

Time:01-02

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

  • Related