Search code examples
aws-lambdaamazon-sesaws-amplify

Lambda using assumed-role instead of execution role


I've created a lambda that use both DynamoDB and SES with amplify.

The resource already had this working policy for dynamoDB:

{
              "Effect": "Allow",
              "Action": [
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:PutItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem"
              ],
              "Resource": [
                {
                  "Ref": "storageuserArn"
                },
                {
                  "Fn::Join": [
                    "/",
                    [
                      {
                        "Ref": "storageuserArn"
                      },
                      "index/*"
                    ]
                  ]
                }
              ]
            },

And I added the following to use SES(The ARN is correct and the email is validated):

{
              "Effect": "Allow",
              "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail",
                "ses:SendTemplatedEmail"
              ],
              "Resource": [
                "arn:aws:ses:region:xxxx:identity/email"
              ]
            }

This adds the access correctly and I can see the grant in lambda-execution-policy in Roles-Summary.

But when I try to execute the function I get the following error:

"User `arn:aws:sts::x:assumed-role/lambdanamexxx-dev/lambdaname-dev' is not authorized to perform `ses:SendTemplatedEmail' on resource `arn:aws:ses:region:xxxx:configuration-set/email'"

Now, in the code I'm not using anything about the assumed-role, i just call SES in the function:

async function sendConfirmationCode(email, code) {
  const ses = new AWS.SES({ region: "region" });

  const templateDate = {
    "code": code
  };

  // Create sendTemplatedEmail params 
  const params = {
    Destination: { /* required */
      ToAddresses: [email]
    },
    Source: 'source-email', /* required */
    Template: 'reset-password', /* required */
    TemplateData: JSON.stringify(templateDate),
  };
  const result = await ses.sendTemplatedEmail(params).promise();
}

What's the reason for this lambda to use assumed-role instead of execution role? The DynamoDB calls works without any problem.

What should I do? Grant access to ses to this assumed role (and how can I do it) or change something in the SES params?


Solution

  • "User `arn:aws:sts::x:assumed-role/lambdanamexxx-dev/lambdaname-dev` is not authorized to perform `ses:SendTemplatedEmail' on resource `arn:aws:ses:region:xxxx:configuration-set/email'"
    

    When you assign an execution role to a Lambda Function, it just makes an AssumeRole API call for that role behind the scenes, so the principal being arn:aws:sts::x:assumed-role/lambdanamexxx-dev/lambdaname-dev is expected.

    You are getting the error because your IAM policy is not providing the required access.

    {
      "Effect": "Allow",
      "Action": [
        "ses:SendEmail",
        "ses:SendRawEmail",
        "ses:SendTemplatedEmail"
      ],
      "Resource": [
        "arn:aws:ses:region:xxxx:identity/email"
      ]
    }
    

    This IAM policy is only allowing ses:SendTemplatedEmail access for the resource arn:aws:ses:region:xxxx:identity/email.

    However, along with the above resource, ses:SendTemplatedEmail also requires access to the resource arn:aws:ses:region:xxxx:configuration-set/email, as mentioned in the error.

    The documentation for SES IAM keys states that the ses:SendTemplatedEmail supports multiple resource types. You will need to specify all of the applicable resources required for your action if you are not specify resource as a wildcard ('*').