3

I am trying to give lambda execution access to select members within a group. Users are authenticated via PingFederate. I am having issue granting this selective access to federated user.

I have a custom IAM policy (allow-lambda-invocation-selective) attached to this role. Although the policy seems to pass validation and policy simulation shows access is allowed, when I try to execute the lambda function I get message

Calling the invoke API action failed with this message: User:arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:123456789012:function:my-lambda-function

Here is my policy: allow-lambda-invocation-selective

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:InvokeAsync",
                "lambda:ListVersionsByFunction",
                "lambda:GetFunction",
                "lambda:ListAliases"
            ],
            "Resource": "arn:aws:lambda:*:123456789012:function:my-lambda-function",
            "Condition": {
                "StringEquals": {
                    "aws:userid": "arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234"
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "lambda:ListFunctions",
                "lambda:ListEventSourceMappings",
                "lambda:ListLayers",
                "lambda:ListLayerVersions"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:userid": "arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234"
                }
            }
        }
    ]
}

Am i missing something?

Scott T.
  • 6,152
  • 1
  • 26
  • 32
dadarw25
  • 33
  • 2

1 Answers1

0

I'm trying to understand your problem. Correct me if I made a wrong supposition.

  1. Every group/user already have its own role.

When you authenticate your users, they have their assumed role. myuser1234, when authenticated, will receive arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 role, right? Is it possible to create one role for each group and remove the conditions property (check item 2 explaining why)?

// role-for-grp-l2
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:InvokeAsync",
                "lambda:ListVersionsByFunction",
                "lambda:GetFunction",
                "lambda:ListAliases"
            ],
            "Resource": "arn:aws:lambda:*:123456789012:function:my-lambda-function"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "lambda:ListFunctions",
                "lambda:ListEventSourceMappings",
                "lambda:ListLayers",
                "lambda:ListLayerVersions"
            ],
            "Resource": "*"
        }
    ]
}
  1. The problem with aws:userid

Reading the docs about the key aws:userid we can find this key has the value given by role id:caller-specified-role-name,

where role id is the unique id of the role and the caller-specified-role-name is specified by the RoleSessionName parameter passed to the AssumeRole request.

So aws:userid has value like AIDAJQABLZS4A3QDU576Q:SomeNameYouGive. Because this, your condition never match arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 and then user cannot assume that actions.

  1. Using conditions another way

Assuming RoleSessionName is the user name, you can use conditions this way:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:InvokeAsync",
                "lambda:ListVersionsByFunction",
                "lambda:GetFunction",
                "lambda:ListAliases"
            ],
            "Resource": "arn:aws:lambda:*:123456789012:function:my-lambda-function",
            "Condition": {
                "StringLike": {
                    "aws:userid": "*:myuser1234"
                }
            }
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "lambda:ListFunctions",
                "lambda:ListEventSourceMappings",
                "lambda:ListLayers",
                "lambda:ListLayerVersions"
            ],
            "Resource": "*",
            "Condition": {
                "StringLike": {
                    "aws:userid": "*:myuser1234"
                }
            }
        }
    ]
}

if you prefer, you may remove * wildcard getting role id using AWS CLI with the command:

aws iam get-role --role-name ROLE_NAME

and changing condition as follows:

"Condition": {
   "StringEquals": {
       "aws:userid": "ROLE_ID:myuser1234"
   }
}

Pedro Arantes
  • 5,113
  • 5
  • 25
  • 60
  • Thank you for your reply Pedro. Apologies if above was not clear. The role that every member of group gets is "role-for-grp-l2". i.e. arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/ So user1s arn will be arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/user1 While for user myuser1234 will be arn:aws:sts::123456789012:assumed-role/role-for-grp-l2/myuser1234 I just want specific user within this group (myuser1234) to be allowed to execute lambda functions. I can not create separate group and move this user (myuser1234). So i have to use a conditional. – dadarw25 Jun 01 '19 at 18:35
  • @dadarw25 check my update out. You may compare the last part of `aws:userid` with user name. – Pedro Arantes Jun 01 '19 at 22:02