0

In client-side javascript, I set:

    AWS.config.credentials = { 
        "accessKeyId": ak,  // starts with "AKIA..."
        "secretAccessKey": sk // something long and cryptic
    };

Then eventually call

    var lambda = new AWS.Lambda({apiVersion: '2015-03-31'});
    var params = {
      FunctionName: 'my-function-name',
      InvokeArgs : my_data
    };
    lambda.invokeAsync(params, function(err, data) {
    ...

The HTML request seems to contain the correct access key:

    authorization:AWS4-HMAC-SHA256 Credential=AKIA...

And in server-side node.js, I don't manually set any AWS credentials, with the understanding that setting them in the client-side is sufficient, as:

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

Following the request, the server's upload handler gets called as expected, but within that handler, s3.putObject() fails with an Access Denied error. Trying to debug this, I added console.log(AWS.config.credentials) to the upload handler, and Cloudwatch is showing:

    accessKeyId: 'ASIA...

I don't recognize the accessKeyId that is shown, and it certainly doesn't match the one provided in the request header. Am I doing something wrong here, or is this expected behavior?

Mike Godin
  • 3,727
  • 3
  • 27
  • 29

1 Answers1

1

The Lambda function does not use the AWS credentials you used in your client-side JavaScript code. The credentials in your client-side code were used to issue a Lambda.invoke() command to the AWS API. In this context, the credentials you are using on the client-side only need the Lambda invoke permission.

Your Lambda function is then invoked by AWS Lambda service. The Lambda service will attach the IAM Execution Role to the invocation that you specified when you created/configured the Lambda function. That IAM Execution Role is what needs to have the appropriate S3 access.

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • With this information and this answer to a related question: https://stackoverflow.com/a/41933694/256305, I was able to avoid the s3.putObject errors by setting the Bucket policy's Principal user to the arn of lambda function's Execution Role. – Mike Godin Nov 20 '17 at 17:10
  • Personally, I would add the appropriate IAM permissions to the Lambda execution role (via an IAM policy) instead of using an S3 bucket policy. – Mark B Nov 20 '17 at 17:21
  • I would prefer add IAM permissions to the Lambda execution role as well, but It did not appear to work, even when enabling all 108 or so S3 permissions in the policy. I wonder if could be a side-effect of the bucket also being configured for Static website hosting? – Mike Godin Nov 20 '17 at 17:31
  • No it's not related to the bucket being configured for static website hosting. However if you already had some sort of bucket policy in place that could have been preventing the Lambda function from accessing it. – Mark B Nov 20 '17 at 17:32