RakeshKalwa
RakeshKalwa

Reputation: 781

Access Denied while sending email from AWS SES in Lambda function

I am trying to send an email using Amazon SES in AWS Lambda function, For this i am facing the following error.

AccessDenied: User arn:aws:sts::XXXXX:assumed-role/lambda_basic_execution/awslambda_XXXX' is not authorized to performses:SendEmail' on resource `arn:aws:ses:us-west-2:XXX:identity/[email protected]'

I have granted permission for

"ses:SendEmail", "ses:SendRawEmail" for the IAM role.

Upvotes: 54

Views: 70275

Answers (11)

Balaji Sukumaran
Balaji Sukumaran

Reputation: 79

The other answers suggesting the use of Resource: '*' will work because you are within an AWS Free Tier sandbox. Within the sandbox, both the from and to addresses need to be registered and verified. When attempting to send an email using Lambda or some other AWS services with a specific SES email ARN (typically the from address), it will not have scope for the to address. Therefore, by setting Resource: '*', you are also including the to address within the scope.

Upvotes: 0

Zeke
Zeke

Reputation: 652

In AWS console go to SES. You have to create SMTP credentials, SES sends you to IAM. Once you have the SMTP user there in the SMTP user you will find the credentials tab. Create the access key. Don't forget to save the secret access key.

Then you can check that the credential key work fine with this code:

$SesClient = new SesClient([
    'version' => '2010-12-01',
    'region'  => 'us-east-2',
    'credentials' => [
        'key'    => 'AKERTCVHAU4ODZ5VQZWP',
        'secret' => '88b7KEDS/XrmPjvy0YukQoPOAlW3eq+OnuDcyl0K',
    ],  
]);

AWS recommend to use the /.aws folder with a file named credentials (without extension) to put the credentials there:

[default]
aws_access_key_id = AKERTCVHAU4ODZ5VQZWP
aws_secret_access_key = 88b7KEDSXrmPjvy0YukQoPOAlW3eq+OnuDcyl0K

Then in IAM go to the SMTP user, permissions tab and edit the policy. Check you have this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
        "Effect": "Allow",
        "Action": [
            "ses:SendRawEmail",
            "ses:SendEmail"
            ],
        "Resource": "*"
        }
    ]
}

Upvotes: 2

PadmaBajra
PadmaBajra

Reputation: 33

You can go to IAM > Users > and the user you have > Permissions and then under the Permissions boundary, I had the permissions boundary S3FullAccess then I changed it to SESFullAcess. It solved the problem for me

Upvotes: 0

Riot
Riot

Reputation: 16726

I found @modsquadron's template.yaml answer didn't work, but this variation does - if you are configuring policies for a SAM Lambda, try:

template.yaml

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Policies:
        - Statement:
            - Sid: SESSendEmailToAllPolicy
              Effect: Allow
              Action:
                - 'ses:SendEmail'
                - 'ses:SendRawEmail'
                - 'ses:SendTemplatedEmail'
              Resource: '*'

Upvotes: 0

Aviv
Aviv

Reputation: 14517

Solution: You got permission error. your lambda iam identity needs to implement this missing iam policy - right action ( ses:SendEmail ) and right effect ( Allow ) to gain access permissions to this resource ( verified domain - arn ). on terraform you can add the following iam policy:

  statement {
    actions   = ["ses:SendEmail"]
    effect    = "Allow"
    resources = ["arn:aws:ses:us-west-2:XXX:identity/[email protected]"]
    sid = "emailFromAWSLambdaServerlessMachine"
  }

As a result - your policy will look like following:

{
  "Effect":"Allow",
  "Action":[
    "ses:SendEmail"
  ],
  "Resource":"arn:aws:ses:us-west-2:XXX:identity/[email protected]",
  "Sid": "emailFromAWSLambdaServerlessMachine"
}

P.S try avoid applying * as a resource or an action and limit access as much as possible for mitigate a security risks.

Upvotes: 2

Mark Simon
Mark Simon

Reputation: 752

For Serverless Components yaml:

...
inputs:
  name: ${name}-${stage}
  region: ...
  service: lambda.amazonaws.com
  policy:
    - Effect: Allow
      Action:
        - ses:SendEmail
        - ses:SendRawEmail
      Resource: '*'

Upvotes: 0

Abdelhadi Abdo
Abdelhadi Abdo

Reputation: 412

As what others said you should add this two permissions: ses:SendEmail,ses:SendRawEmail

I just want to add explaination for those who use Serverless framework

In serverless.yml:

provider:
  name: aws
  stage: dev
  runtime: nodejs10.x
  region: us-west-1
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
        - lambda:InvokeFunction
        - ses:SendEmail            # add this
        - ses:SendRawEmail         # add this
      Resource: '*'                # add this

Upvotes: 5

tomcat
tomcat

Reputation: 1860

IAM Policy fixed the issue. Policy summary will show if there are any warnings i.e. resource does not exist etc.

JSON needs following

       {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "ses:SendRawEmail"
            ],
            "Resource": "*"
        }

Upvotes: 3

modsquadron
modsquadron

Reputation: 664

If you are configuring policies for a SAM Lambda or using a YAML configuration file, you would use something like this:

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'your-email-lambda'

Resources:
  YourEmailFunction:
    Type: AWS:Serverless::Function
    Properties:
      Policies:
        - Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - 'ses:SendEmail'
                - 'ses:SendRawEmail'
              Resource: '*'

Upvotes: 13

Nishith
Nishith

Reputation: 1118

So, I was also having the same problem which Rakesh has explained but couldn't understand the steps he was saying to do so here is a detailed explanation with steps.

You need to do the following Security, Identity & Compliance -> IAM -> Roles -> select your lambda function -> then edit policy -> open it in JSON and add the below part

{
  "Effect":"Allow",
  "Action":[
    "ses:SendEmail",
    "ses:SendRawEmail"
  ],
  "Resource":"*"
}

or you can do as per requirement from these policy examples https://docs.aws.amazon.com/ses/latest/DeveloperGuide/control-user-access.html#iam-and-ses-examples-email-sending-actions also, you need to verify the email address first so don't forget that. Hope this helps everyone.

Upvotes: 74

RakeshKalwa
RakeshKalwa

Reputation: 781

After a long debugging i got the issue, "lambda_basic_execution" role need to be granted with permission to access "ses:SendEmail", "ses:SendRawEmail".

Where i was trying to grant permission for the new IAM role i have created, but lambda function is mapped to "lambda_basic_execution" so there is a mismatch.

Reference - http://docs.aws.amazon.com/ses/latest/DeveloperGuide/control-user-access.html#iam-and-ses-examples-email-sending-actions

Upvotes: 11

Related Questions