IndyStef
IndyStef

Reputation: 787

AWS S3 putObjectTagging fails with AccessDenied in node.js lambda function

I have a serverless application in JS, running in AWS lambda on node.js 8.10. It gets triggered by S3 events, and creates a copy of newly uploaded S3 items in a different bucket, with versioning. The lambda function is given a role that contains the following policies:

      {
        "PolicyName" : {"Fn::Join": ["", [{"Ref": "AWS::Region"}, "-", "S3LambdaPolicy"]]},
        "PolicyDocument": {
          "Version" : "2012-10-17",
          "Statement" : [
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning",
                "s3:GetObjectTagging",
                "s3:PutObject",
                "s3:PutObjectTagging",
                "s3:ListBucket",
                "s3:ListBucketVersions"
              ],
              "Resource": "arn:aws:s3:::*"
            }
          ]
        }
      }

The function calls this s3 function after copying the item to the targetBucket (and waiting for it to be there):

        let tagging = {
            Bucket: targetBucket,
            Key: targetKey,
            Tagging: {
                TagSet: [
                    {
                        Key: "SourceBucket",
                        Value: sourceBucket,
                    },
                    {
                        Key: "SourceKey",
                        Value: key
                    }
                ]
            }
        };
        if (data.VersionId) {
            tagging.VersionId = data.VersionId;
        }
        s3.putObjectTagging(tagging, function(err, data){
            if (err) {
                console.log(err);
            } else {
                console.log("Set the tagging to " + JSON.stringify(tagging));
            }
        });

This always fails with an access denied error:

2018-11-06T12:06:24.070Z 389637c4-e1bc-11e8-8eec-8b4d06f7596c { AccessDenied: Access Denied at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:577:35) ... message: 'Access Denied', code: 'AccessDenied', region: null, time: 2018-11-06T12:06:24.069Z, requestId: '178F863CC6FB4960', extendedRequestId: 'sYbGkGb+hgOWtWp1XPkqtoVRv2XxAg04axRAUaeF0VtMMzMYYyPMkTrwWpx3xUBF0zalKzIJAI8=', cfId: undefined, statusCode: 403, retryable: false, retryDelay: 39.20736560394356 }

I am not sure what I am missing here, and would appreciate any help with this problem.

Thx,

Stefan

Upvotes: 2

Views: 3495

Answers (1)

IndyStef
IndyStef

Reputation: 787

Found the solution myself: As I am using versioning, I also needed to add the specific policies for getting/putting tags on versioned objects. So this is the rule that works for me:

      {
        "PolicyName" : {"Fn::Join": ["", [{"Ref": "AWS::Region"}, "-", "S3LambdaPolicy"]]},
        "PolicyDocument": {
          "Version" : "2012-10-17",
          "Statement" : [
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning",
                "s3:GetObjectTagging",
                "s3:GetObjectVersionTagging",
                "s3:PutObject",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionTagging",
                "s3:ListBucket",
                "s3:ListBucketVersions"
              ],
              "Resource": "arn:aws:s3:::*"
            }
          ]
        }
      }

Upvotes: 5

Related Questions