Search code examples
node.jsamazon-s3serverless-frameworkaws-serverless

serverless s3 AccessDenied


I spent hours on this issue without understanding why the Access Denied

Here my corresponding part of the serverless.yml

provider:
        name: aws
        runtime: nodejs12.x
        region: eu-central-1
        environment:
                STAGE: ${opt:stage, self:provider.stage}
        iamRoleStatements:
                - Effect: Allow
                  Action:
                          - s3:GetObject
                          - s3:PutObject
                  Resource:
                          - arn:aws:s3:::<bucket-1>/*
                          - arn:aws:s3:::<bucket-2>/*
                - Effect: Allow
                  Action:
                          - s3:ListBucket
                  Resource:
                          - arn:aws:s3:::<bucket-1>
                          - arn:aws:s3:::<bucket-2>

Then running

return s3DataProvider.upload({
    Bucket: store.bucket,
    ACL: 'public-read',
    Body: sm.toString(),
    Key: `front/${process.env.STAGE}/sitemap.xml`,
    ContentType: 'text/xml'
}).promise()

where store.bucket is by <bucket-1> or <bucket-2>

I always have

ERROR   AccessDenied: Access Denied
    at Request.extractError (/var/task/node_modules/aws-sdk/lib/services/s3.js:837:35)
    at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:688:14)
    at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:690:12)
    at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
  code: 'AccessDenied',
  region: null,
  time: 2021-01-25T21:48:47.259Z,
  requestId: '546A64CC9D503FA8',
  extendedRequestId: 'hoRF0wDih8jRimR7Ew0ajMhgf4qQ88DCXjWM6bdd1CUsP+9OdpNkiXwZz1UFAK+s7L/clFH4U2c=',
  cfId: undefined,
  statusCode: 403,
  retryable: false,
  retryDelay: 24.899574651815936
}

Solution

  • I'm not 100% sure but I guess there's s3:PutObjectAcl missing as your setting public-read for the object.

    Edit: probably be safe and also grant s3:GetObjectAcl. A lot of discussions and similar issues can be found here: Getting Access Denied when calling the PutObject operation with bucket-level permission