5

I just can't figure out what is wrong with my Bucket Policy in AWS. Trying to let a Lambda function to access and read an email from the S3 Bucket. But I keep getting "Access Denied"

Please note that I notice the email file is being created in the bucket. Here is my last version of the Bucket Policy:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[MY NUMBER]:root"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[MY BUCKET NAME]/*"
        }
    ]
}

I have tried also with "Principal": {"Service": "ses.amazonaws.com"}, alas

I keep getting Access Denied:

2017-09-17T14:12:14.231Z 10664101-9bb2-11e7-ad43-539f3e1a8626
{
    "errorMessage": "Access Denied",
    "errorType": "AccessDenied",
    "stackTrace": [
        "Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:577:35)",
        "Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)",
        "Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)",
        "Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)",
        "Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
        "AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
        "/var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
        "Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
        "Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)",
        "Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:115:18)"
    ]
}

And here is my Lambda function:

var AWS = require('aws-sdk');
var s3 = new AWS.S3();

var bucketName = '[MY BUCKET NAME]';

exports.handler = function(event, context, callback) {
    console.log('Process email');

    var sesNotification = event.Records[0].ses;
    if(!sesNotification) {
        callback(null, null);
        return;
    }

    console.log("SES Notification:\n", JSON.stringify(sesNotification, null, 2));

    // Retrieve the email from your bucket
    s3.getObject({
            Bucket: bucketName,
            Key: sesNotification.mail.messageId
        }, function(err, data) {
            if (err) {
                console.log(err, err.stack);
                callback(err);
            } else {
                console.log("Raw email:\n" + data.Body);

                // Custom email processing goes here

                callback(null, null);
            }
        });
};

After long time and many versions of the Bucket Policy I am thinking of trying another solution and drop AWS.

Any ideas ?

aviv
  • 2,719
  • 7
  • 35
  • 48

1 Answers1

9

You need to create an IAM role and attach it to the Lambda function with S3FullAccess policy or with finegrained permission for the specific bucket and actions (Recommended).

Also make sure trust relationship configuration is added to the role.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com"
        ]
      }
    }
  ]
}

Note: In your current setup, it seems like you have configured the bucket policy which grants read access to the root user.

Ashan
  • 18,898
  • 4
  • 47
  • 67
  • thanks for the answer. I have created an IAM user with fullS3Access. Yet I couldn't find where I attach it to the Lambda function nor where can I add it to the S3 Bucket ... – aviv Sep 17 '17 at 14:51
  • You need to create an IAM role instead of a user and also add the trust relationships for Lambda inside the role (Apart from the policy). Check the updated answer – Ashan Sep 17 '17 at 14:52
  • Did both. Still get "Access Denied". What should be my Policy Bucket Principal ? – aviv Sep 17 '17 at 15:12
  • 1
    For testing purposes. First remove the bucket policy you added from S3. Create a iam role with s3 full access and with the mentioned trust relationship. Then attach the role to lambda and tryout? – Ashan Sep 17 '17 at 15:14
  • Thanks. Now I get "The specific key does not exist" which is another problem :-) – aviv Sep 17 '17 at 15:31
  • please update the answer regarding attaching the S3FullAccess to the Lambda Role and I will set is the chosen answer. – aviv Sep 17 '17 at 15:32
  • I have updated the answer. Also mote that for security it is recommended to whitelist the specific bucket resource and actions within the policy. – Ashan Sep 17 '17 at 15:38