Why is my access denied on s3 (using the aws-sdk for Node.js)?

50,721

Solution 1

The problem was that my new IAM user didn't have a policy attached to it. I assigned it the AmazonS3FullAccess policy and now it works.

As pointed out in the comments, a more restrictive policy would be much safer

Solution 2

This could also happen if you're trying to set ACL to "public-read" but the bucket is blocking public access. For example if you mean to upload static assets to a misconfigured S3 bucket. You can change it in your bucket settings.

Solution 3

FullAccess in your policy is not required. You can try something like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:Put*",
                "s3:Get*",
                "s3:List*",
                "s3:Delete*"
            ],
            "Resource": [
                "arn:aws:s3:::bucket/*",
                "arn:aws:s3:::bucket"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        }
    ]
}

Solution 4

These errors can occur when the object which you are trying to read does not exist. From what I understood the AWS errors are not so clear in these situations.

Validate if your key/bucket is correct and if you are sending the correct params on the API method.

I already got this problem two times:

  • when I was replacing the key param with the bucket param and vice versa and I was trying to read an s3 object using the getObject() method.
  • when I was trying to copy a file to a location that did not exist using the copyObject() method.

Solution 5

"code":"AccessDenied","region":null,"time":"2020-05-24T05:20:56.219Z","requestId": ... 

Applied the below policy in s3 aws console > Bucket policy editor of 'Permissions' tab to get rid of the above error,

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<IAM-user-ID>:user/testuser"
            },
            "Action": [
                "s3:ListBucket",
                "s3:ListBucketVersions",
                "s3:GetBucketLocation",
                "s3:Get*",
                "s3:Put*"
            ],
            "Resource": "arn:aws:s3:::srcbucket"
        }
    ]
}
Share:
50,721
Shawn
Author by

Shawn

I learned about the web by myself thanks to free and open-source software and the original spirit of the Internet. I am thankful for having found the web for it gave me a path towards learning that school couldn't offer and eventually a long and interesting career. To keep things fresh, I have recently started pivoting towards consulting and mentorship. I guess I need to see more people and fewer computers.

Updated on October 21, 2021

Comments

  • Shawn
    Shawn over 2 years

    I'm trying to read an existing file from my s3 bucket, but I keep getting "Access Denied" with no explanation or instructions on what to do about it. Here is the code I am using:

    'use strict'
    
    var AWS = require('aws-sdk')
    const options = {
      apiVersion: '2006-03-01',
      params: {
        Bucket: process.env['IMAGINATOR_BUCKET']
      },
      accessKeyId: process.env['IMAGINATOR_AWS_ACCESS_KEY_ID'],
      secretAccessKey: process.env['IMAGINATOR_AWS_SECRET_ACCESS_KEY'],
      signatureVersion: 'v4'
    }
    console.log('options', options)
    var s3 = new AWS.S3(options)
    
    module.exports = exports = {
      get (name, cb) {
        const params = {
          Key: name + '.json'
        }
        console.log('get params', params)
        return s3.getObject(params, cb)
      },
      set (name, body, cb) {
        const params = {
          Key: name + '.json',
          Body: body
        }
        console.log('set params', params)
        return s3.putObject(params, cb)
      }
    }
    

    And this is what I'm getting as output when using the get method and logging the error provided in the callback (with sensitive information censored out):

    options { apiVersion: '2006-03-01',
      params: { Bucket: CENSORED_BUT_CORRECT },
      accessKeyId: CENSORED_BUT_CORRECT,
      secretAccessKey: CENSORED_BUT_CORRECT,
      signatureVersion: 'v4' }
    get params { Key: 'whitelist.json' }
    err { [AccessDenied: Access Denied]
      message: 'Access Denied',
      code: 'AccessDenied',
      region: null,
      time: Wed Sep 21 2016 11:17:50 GMT-0400 (EDT),
      requestId: CENSORED,
      extendedRequestId: CENSORED,
      cfId: undefined,
      statusCode: 403,
      retryable: false,
      retryDelay: 20.084538962692022 }
    /Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:31
                throw err;
                ^
    
    AccessDenied: Access Denied
        at Request.extractError (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/services/s3.js:538:35)
        at Request.callListeners (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
        at Request.emit (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
        at Request.emit (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:668:14)
        at Request.transition (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:22:10)
        at AcceptorStateMachine.runTo (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/state_machine.js:14:12)
        at /Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/state_machine.js:26:10
        at Request.<anonymous> (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:38:9)
        at Request.<anonymous> (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/request.js:670:12)
        at Request.callListeners (/Users/shawn/git/vigour-io/imaginate/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
    

    Now I'm not sure what to do beacuse I think I'm doing things correctly according to the docs, but it's not working and the error message doesn't say why my access is denied... Any idea what the next step should be to get this working?