AccessDeniedException: User is not authorized to perform: lambda:InvokeFunction
Asked Answered
K

11

127

I'm trying to invoke a lambda function from node.

var aws = require('aws-sdk');
var lambda = new aws.Lambda({
    accessKeyId: 'id',
    secretAccessKey: 'key',
    region: 'us-west-2'
});

lambda.invoke({
    FunctionName: 'test1',
    Payload: JSON.stringify({
        key1: 'Arjun',
        key2: 'kom',
        key3: 'ath'
    })
}, function(err, data) {
    if (err) console.log(err, err.stack);
    else     console.log(data);
});

The keys are for an IAM user. The user has AWSLambdaExecute and AWSLambdaBasicExecutionRole policies attached.

I get a permission error: AccessDeniedException: User: arn:aws:iam::1221321312:user/cli is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-west-2:1221321312:function:test1

I read the docs and several blogs, but I'm unable to authorise this user to invoke the lambda function. How do get this user to invoke lambda?

Kirkwood answered 28/5, 2016 at 10:53 Comment(1)
I heartily wish there were an aws cli or web interface to fix this. aws add-access "AccessDeniedException: User: ARN... is not authorized to perform: ACTION on resource: ARN..." maybe prompt you with a couple of description questions and add the access roles.Sinistral
F
174

UPDATE (TL;DR)

There is now also an IAM Managed Policy named AWSLambdaRole that you can assign to your IAM user or IAM role. This should give you the permissions you need.


Original Answer

The AWSLambdaExecute and AWSLambdaBasicExecutionRole do not provide the permissions that are being expressed in the error. Both of these managed policies are designed to be attached to your Lambda function itself, so it runs with these policies.

The error is saying the user under which the nodejs program is running does not have rights to start the Lambda function.

You need to give your IAM user the lambda:InvokeFunction permission:

  1. Find your User in the IAM Management Console and click it.
  2. On the "Permissions" tab, expand the "Inline Policies" section and click the "click here" link to add a policy".
  3. Select a "Custom Policy".
  4. Give your policy a name. It can be anything.
  5. Put this policy in the Policy Document field.

Sample policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1464440182000",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeAsync",
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

In this policy, I have included both methods to invoke lambda methods.

Feudalism answered 28/5, 2016 at 12:52 Comment(10)
This did not work for me, I had to use "lambda:*". In other words had to hit it with a big hammer!Penult
For what you are doing, there's no need to create a custom policy. You can add AWSLambdaRole as a managed policy on the user profile and that's it.Frederiksen
I tried both adding custom policy and attaching "AWSLambdaRole", but I am still getting the AccessDeniedException: <USER> is not authorized to perform: lambda:InvokeFunctionWeise
@lusocoding that worked for me, let me know if you post it as an answer of its own ;)Elephantine
Works for me but it took some minutes to an hour before the changes took effectUniocular
AWSLambdaRole didn't work for me, i needed to create the inline policy with lambda:InvokeAsync, since i have event function typesBedtime
the Action "lambda:InvokeAsync" is deprecated, you just need the "lambda:InvokeFunction"Camel
Adding AWSLambdaRole worked for me, but it took a few minutes to wait for it to workEllswerth
This is the perfect example of Amazon's trash UI. Or, to put it more clearly, why don't they just SAY this?!Bensky
WARNING: Using "Resource": "*" has given me a ton of trouble. better to use "arn:aws:lambda:*:*:*" insteadSulphathiazole
A
21

I'm using Serverless framework, and I had to also add arn:aws:lambda as a resource in my serverless.yml in order to use lambda.invoke.

 iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
        - lambda:InvokeFunction # Added this like mentioned above
      Resource:
        - arn:aws:dynamodb:us-east-1:*:*
        - arn:aws:lambda:us-east-1:*:* # Had to add this too
Azure answered 16/10, 2018 at 3:11 Comment(3)
This solved the issue for me (none of the other answers worked for me).Neophyte
Thanks, this is what I was looking for. Just a note that this config should be put under the "provider" section, forum.serverless.com/t/…Champlain
Not necessarily, it can be declared under the function yml definition as well in iamRoleStatementsSpindly
S
11

This solution worked for me:

  1. Attaching AWSKeyManagementServicePowerUser policy from the policy list (without that I got an error on "iam:listRole")

  2. Adding lambda:ListFunctions to the custom policy defined by @Matt Houser

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1464440182000",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeAsync",
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
Scoria answered 19/7, 2017 at 13:2 Comment(0)
R
7

Go to IAM, select the user and click on "add permissions". In the list of permission , you can simply search with all those policies with lambda,and check the ones you want in order to execute the lambda from console.

enter AWS IAM permissions

River answered 22/5, 2018 at 3:18 Comment(0)
T
4

If you just use the policies that AWS provides you have to give to the user or the group it belongs Policy from AWS

Tomasine answered 19/9, 2018 at 14:18 Comment(1)
Adding` AWSCodeDeploy` worked form me when calling Lambda from iOS.Becht
B
3

I solved this by adding the AWSLambdaFullAccess permissions to the user.

  1. Within IAM Users, click add permissions
  2. Select "Attach existing policies directly"
  3. Search for AWSLambdaFullAccess, select it and click next:review at the bottom of the page.
  4. Click Add Permissions

And that should do it.

Batha answered 20/3, 2018 at 17:40 Comment(3)
I had to add "AWSCodeDeployRoleForLambda"Hildegardhildegarde
Agree with @KeithNorman, AWSLambdaFullAccess alone didn't do it for me.Mabe
note AWSLambdaFullAccess & AWSLambdaReadOnlyAccess are now deprecated. See here: docs.aws.amazon.com/lambda/latest/dg/…Hickson
S
2

This worked for me:

{
    "Sid": "PermissionToInvoke",
    "Effect": "Allow",
    "Action": [
      "lambda:InvokeFunction"
    ],
    "Resource": "arn:aws:lambda:*:*:*:*"
}
Saccharose answered 14/7, 2020 at 19:31 Comment(2)
What is it about the Sid? Is this arbitrary?Sumter
@Sumter You put a unique name in the Sid for identification of that permission from othersSaccharose
W
1

If you want to allow one lambda function to invoke another one you should update policies of your lambda role.

This is a Terraform example:

Set Up the IAM Roles and Policies:

resource "aws_iam_role" "lambda_1_role" {
    name   = "Lambda_1_Role"
    assume_role_policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Effect": "Allow",
            "Sid": ""
        }
    ]
}
EOF
}

Add IAM Policy:

resource "aws_iam_policy" "iam_policy_for_lambda_1" {
    name         = "aws_iam_policy_for_terraform_aws_lambda_1_role"
    path         = "/"
    description  = "AWS IAM Policy for managing aws lambda 1 role"
    policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
        ],
        "Resource": "arn:aws:logs:*:*:*",
        "Effect": "Allow"
    },
    {
        "Sid": "Stmt1464440182000",
        "Effect": "Allow",
        "Action": [
            "lambda:InvokeAsync",
            "lambda:InvokeFunction"
        ],
        "Resource": [
            "*" 
        ]
    }
    ]
}
EOF
}

Don't forget to specify your Resource. Don't use the wildcard for production.

Attach IAM Policy to IAM Role:

resource "aws_iam_role_policy_attachment" "attach_iam_policy_to_iam_role_lambda_1" {
    role        = aws_iam_role.lambda_1_role.name
    policy_arn  = aws_iam_policy.iam_policy_for_lambda_1.arn
}

Create a lambda:

resource "aws_lambda_function" "lambda_1" {
    function_name  = "Lambda_1"
    filename       = "../lambda-1.zip"
    role           = aws_iam_role.lambda_1_role.arn
    handler        = "index.handler"
    runtime        = "nodejs16.x"
    depends_on     = [aws_iam_role_policy_attachment.attach_iam_policy_to_iam_role_lambda_1]
}
Whyalla answered 16/2, 2023 at 5:49 Comment(0)
S
0

For SAM templates, make sure you have added the lambda resource to your AppSync resource:

AppSyncApiServicePolicy:
Type: AWS::IAM::Policy
Properties:
  PolicyName: AppSyncLambdaInvokePolicy
  Roles:
    - !Ref AppSyncApiServiceRole
  PolicyDocument:
    Version: 2012-10-17
    Statement:
      - Effect: Allow
        Action: lambda:InvokeFunction
        Resource:
          - !GetAtt GetMessages.Arn // added lambda resource
          - !GetAtt SendMessage.Arn // added lambda resource
Spatial answered 9/5, 2023 at 21:37 Comment(0)
B
0

For running lambda functions from CloudWatch alarm: you should add resouce-based policy in your lambda configuration and the principal should be lambda.alarms.cloudwatch.amazonaws.com. These principals didn't work for me:

  • cloudwatch.amazonaws.com
  • logs.amazonaws.com
Besprent answered 14/2, 2024 at 14:51 Comment(0)
S
0

2024 updated

If your error was about a role, not a user:

User: arn:aws:sts::123456789:assumed-role/acme-role-fda27de8/acme is not authorized to perform: 
lambda:InvokeFunction on resource:
arn:aws:lambda:us-east-1:123456789:function:acme-function because 
no identity-based policy allows the lambda:InvokeFunction action

You will have this information

  • role: acme-role-fda27de8
    • automatically created for some automated process like terraform, another aws service, jenkins, you using the ui, etc
  • resource or your function name: arn:aws:lambda:us-east-1:123456789:function:acme-function

The following steps if for the specified scenario but I think it could work for a proper user instead role.

Step 1

Go to iam

enter image description here

Search the role and click on it

enter image description here

Step 2

Create an inline policy

enter image description here

enter image description here

Add the resource name

enter image description here

Click on next , set a name and click on create policy

enter image description here

Step 3

Validate that the new policy was created

enter image description here

Steapsin answered 5/4, 2024 at 13:24 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.