1
votes

I'm having issues with calling a lambda in account B from a different lambda in account A.

Account A's role arn is arn:aws:iam::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP

Account A's role name is DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP

Account B's role name is Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1

Account B's role arn is arn:aws:lambda:us-east-1:462087996972:function:GetActiveDeviceIdsLambdaChris

For account A my lambda role has the following permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
            "Effect": "Allow"
        },
        {
            "Action": "lambda:InvokeFunction",
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
            "Effect": "Allow"
        }
    ]
}

My lambda in account B has the following role as defined using cloudformation:

    "CrossAccountExecutionRoleDemo": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:sts::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP"
              },
              "Action": "sts:AssumeRole"
            },
            {
              "Effect": "Allow",
              "Principal": { "Service": ["lambda.amazonaws.com"] },
              "Action": ["sts:AssumeRole"]
            }
          ]
        }
      }
    },
    "CrossAccountExecutionPolicyDemo": {
      "Type": "AWS::IAM::ManagedPolicy",
      "Properties": {
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": "lambda:InvokeFunction",
              "Resource": { "Fn::GetAtt": ["GetActiveDeviceIdsLambdaDemo", "Arn"] }
            }
          ]
        },
        "Roles": [
          {
            "Ref": "CrossAccountExecutionRoleDemo"
          }
        ]
      }
    }

When I make the following request I get an error

let roleArn = 'arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-CrossAccountExecutionRol-1ANKXFZ6YS23'
sts.assumeRole(
      {
        RoleArn: roleArn,
        RoleSessionName: 'NightlySimService',
      }, function(err, res){ ... }

Error:

' AccessDenied: User: arn:aws:sts::ACCOUNT_A:assumed-role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP/DeviceApiStack-nightlySimServiceLambdaA51B2AFE-JSUFU8F5BZGC is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-CrossAccountExecutionRol-1ANKXFZ6YS23F '

1
The basic flow is: Lambda function in Account-A calls AssumeRole on Role-B. It then uses those temporary credentials to call Invoke on Lambda-B. Role-A does not need to grant Lambda-A permission to call Invoke because Role-A won't be used to call Lamda-B. Instead, Role-B needs to be given permission to invoke Lambda-B.John Rotenstein

1 Answers

1
votes

I can spot two apparent issues in the roles, which could be the cause of your errors.

First. Incorrect principle:

  "Principal": {
      "AWS": "arn:aws:sts::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP"
   },

As you wrote the role arn is arn:aws:iam::ACCOUNT_A:role/DeviceApiStack-simServiceRole427DA44E-1WS2T3INIV6IP, which does not match of what you provided in the Principal.

Second. Incorrect resource:

  {
     "Action": "lambda:InvokeFunction",
     "Resource": "arn:aws:iam::ACCOUNT_B:role/Chris-APIStack1-Q6AJ1PZ8V-LambdaCrossAccountExecut-1N3JU88L5AON1",
     "Effect": "Allow"
  }

The action lambda:InvokeFunction applies to lambda functions, not IAM roles. Thus, the Resource should be ARN of the lambda.

There could be more issues, which are not that obvious at present.