Search code examples
amazon-web-servicesaws-lambdaaws-policiesaws-roles

How to allow IAM user to access lambda function in another account?


I have two AWS accounts. AccountA where IAM user devuser is created, In another account AccountB where lambda is hosted.
In account AccountA I have the following permission policy attached to IAM user devuser

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:InvokeAsync"
            ],
            "Resource": "arn:aws:lambda:us-west-2:AccountB:function:dev-my-lambda"
        }
    ]
}

in AccountB where Lambda is hosted I have the following trust relationship policy attached to lambda's execution role

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AccountA:user/devuser"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

However when I invoke lambda using the access key that is associated with devuser I am getting the following error

User: arn:aws:iam::AccountA:user/devuser is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-west-2:AccountB:function:dev-my-lambda because no resource-based policy allows the lambda:InvokeFunction action


Solution

  • You need to add permissions to the Resource Policy of the Lambda function to allow the devuser to invoke the function. Currently you seem to have attached permissions to the trust relationship of the IAM role that Lambda uses.

    The documentation around this explains this in more detail.

    In a nutshell, you'll have to add something like this to the resource based policy of the Lambda Function.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::AccountA:user/devuser"
                },
                "Action": "lambda:InvokeFunction"
            }
        ]
    }
    

    If you want to use the CLI to create it, the API call should look something like this (I didn't run this myself):

    aws lambda add-permission --function-name <my-function> \
      --statement-id xaccount --action lambda:InvokeFunction \
      --principal <arn:aws:iam::AccountA:user/devuser>