RandomEli
RandomEli

Reputation: 1557

AWS lambda function invocating S3.getObject getting Access Denied

I am using lambda function to thumbnail images in s3 bucket. And I found a sample here: Image conversion using Amazon Lambda and S3 in Node.js. However, after refactoring the code, I got access denied when invocating s3.getObject(). I checked if my IAM policy granted permissions incorrectly, but I had full access to Lambda, S3 and CloudFront. Here's how exception thrown:

async.waterfall([

    function download(next) {
        console.log(srcBucket+ "  "+srcKey);
        s3.getObject({
            Bucket: srcBucket,
            Key: srcKey
        }, next);
        console.log(srcBucket+ "  "+srcKey+ "After");
    }

], function(err, result) {
    if (err) {
        console.error(err);
    }
    // result now equals 'done'
    console.log("End of step " + key);
    callback();
});

Also, how my matchng regex setting is the same as the sample:

var srcBucket = event.Records[0].s3.bucket.name;
var typeMatch = srcKey.match(/\.([^.]*)$/);
var fileName = path.basename(srcKey);
if (!typeMatch) {
    console.error('unable to infer image type for key ' + srcKey);
    return;
}
var imageType = typeMatch[1].toLowerCase();
if (imageType != "jpg" && imageType != "gif" && imageType != "png" &&
    imageType != "eps") {
    console.log('skipping non-image ' + srcKey);
    return;
}

My Lambda policy is:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::*"
      ]
    }
  ]
}

Upvotes: 1

Views: 8081

Answers (4)

Chinthaka Dinadasa
Chinthaka Dinadasa

Reputation: 3461

I've given necessary permissions from S3 side for the Lambda Execution Role ARN

{
    "Version": "2012-10-17",
    "Id": "Policy1663698473036",
    "Statement": [
        {
            "Sid": "Stmt1663698470845",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::434324234:role/file-conversion-lambdaRole"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::file-conversion-bucket/*"
        },
        {
            "Sid": "Stmt1663698470842",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::434324234:role/file-conversion-lambdaRole"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::file-conversion-bucket/processed/*"
        }
    ]
}

Upvotes: 0

Deniz Kaplan
Deniz Kaplan

Reputation: 1609

For those who reached this question and checked all the steps below:

  1. Resource definition is correct for action "s3:*"
"Resource": [
    "arn:aws:s3:::mybucket",
    "arn:aws:s3:::mybucket/*"
]
  1. Lambda role has S3 Permissions (S3FullAccess probably)
  2. File is in the bucket (throws 403 for not found) and bucket and object key information is correct
  3. S3 object level permission for read is not overwritten.

There is an extra step which solved my problem. You may want to check IAM Role definition to remove if any permission boundary blocks to reach S3. You can also look at Permission Boundary Documentation for more information.

Upvotes: 2

RandomEli
RandomEli

Reputation: 1557

I got the inspiration from this as this answer: Reference to error

Therefore, I changed my test event to:

"s3": {
        "configurationId": "testConfigRule",
        "object": {
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901",
          "key": "images/HappyFace.jpg",
          "size": 1024
        }

by given prefix to images/ in the key setting, which I should have done that in my regex setting.

This error message is really confusing, please do check your policy first, and then try to give a full path as your key.

Upvotes: 0

ataylor
ataylor

Reputation: 66059

When a Lambda gets an Access Denied error when trying to use S3, it's almost always a problem with the Lambda's Role Policy. In general, you need something like this to grant access to an S3 bucket from Lambda:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::mybucket",
                "arn:aws:s3:::mybucket/*"
            ],
            "Effect": "Allow"
        }
    ]
}

Upvotes: 5

Related Questions