1
votes

Below is the custom execution role(some-role-serv-LogicalID-GDGGGGGBMW2) created for lambda function(AWS::Serverless::Function) written using SAM template:

{
  "permissionsBoundary": {
    "permissionsBoundaryArn": "arn:aws:iam::111222333444:policy/some-permission-boundary",
    "permissionsBoundaryType": "Policy"
  },
  "roleName": “some-role-serv-LogicalID-GDGGGGGBMW2”,
  "policies": [
    {
      "document": {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Action": "sqs:*",
            "Resource": "arn:aws:sqs:us-east-1:111222333444:someq*",
            "Effect": "Allow"
          },
          {
            "Action": [
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:us-east-1:111222333444:log-group:*",
            "Effect": "Allow"
          }
        ]
      },
      "name": "lambda-policy",
      "type": "inline"
    }
  ],
  "trustedEntities": [
    "lambda.amazonaws.com"
  ]
}

Where some-permission-boundary is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:111222333444:log-group:*"
            ],
            "Effect": "Allow",
        },
        {
            "Action": [
                "sqs:DeleteMessage",
                "sqs:ReceiveMessage",
                "sqs:SendMessage",
                "sqs:ListDeadLetterSourceQueues",
                "sqs:GetQueueAttributes",
                "sqs:GetQueueUrl"
            ],
            "Resource": [
                "arn:aws:sqs:us-east-1:111222333444:someq*"
            ],
            "Effect": "Allow",
        }
    ]
}

some-role-serv-LogicalID-GDGGGGGBMW2 is assigned a permission boundary(some-permission-boundary) in SAM template

Lambda function assumes custom role with below SAM template syntax:

Role: !GetAtt LogicalID.Arn

Amidst deployment,

lambda is created(using sam deploy) from a docker container within EC2,

where is an additional role policy(below) is assumed by EC2:

   {
        "Condition": {
            "StringEquals": {
                "iam:PermissionsBoundary": "arn:aws:iam::111222333444:policy/some-permission-boundary"
            }
        },
        "Action": [
            "iam:CreateRole",
            "iam:AttachRolePolicy",
            "iam:PutRolePolicy",
            "iam:DetachRolePolicy",
            "iam:GetRolePolicy"
        ],
        "Resource": [
            "arn:aws:iam::111222333444:role/some-role*"
        ],
        "Effect": "Allow"
    }

This EC2 policy is supposed to make sure that any custom role(say some-role-serv-LogicalID-GDGGGGGBMW2) that does not have below property:

PermissionsBoundary: !Sub "arn:aws:iam::${AWS::AccountId}:policy/some-permission-boundary"

should not allow creating role some-role-serv-LogicalID-GDGGGGGBMW2

I get below error while stack creation:

enter image description here

Stack is created successfully but,

1) Why sam deploy command gets this error?

2)

Does the EC2 policy disallow custom role(some-role-serv-LogicalID-GDGGGGGBMW2) creation that comes without permission boundary(some-permission-boundary)? as expected...

1

1 Answers

1
votes

The error states that your EC2 instance, entity that is calling sam deploy action does not have permissions to perform iam:GetRolePolicy which really is the case here.

Problem is that while you can restrict the other 4 actions with this condition

"Condition": {
    "StringEquals": {
        "iam:PermissionsBoundary": "arn:aws:iam::111222333444:policy/some-permission-boundary"
    }
}

You can't do the same for GetRolePolicy. This actions can't be restricted by that condition otherwise its effect is nullified. The only service level condition applicable to this action is iam:ResourceTag.

If you go to management console and try to create such IAM policy, you can see this warning caused by combination of your condition with iam:GetRolePolicy action.

This policy defines some actions, resources, or conditions that do not provide permissions. To grant access, policies must have an action that has an applicable resource or condition.

Solution is to split your statement into two. First with that condition to restrict creation of IAM Roles that do not have necessary permission boundaries together with the other IAM actions except of the mentioned iam:GetRolePolicy. Then you should create second statement containing just iam:GetRolePolicy without that condition.

    {
        "Condition": {
            "StringEquals": {
                "iam:PermissionsBoundary": "arn:aws:iam::111222333444:policy/some-permission-boundary"
            }
        },
        "Action": [
            "iam:CreateRole",
            "iam:AttachRolePolicy",
            "iam:PutRolePolicy",
            "iam:DetachRolePolicy"
        ],
        "Resource": [
            "arn:aws:iam::111222333444:role/some-role*"
        ],
        "Effect": "Allow"
    }

and

   {
        "Action": [
            "iam:GetRolePolicy"
        ],
        "Resource": [
            "arn:aws:iam::111222333444:role/some-role*"
        ],
        "Effect": "Allow"
    }

And to answer your second question. Yes, you can use iam:PermissionsBoundary condition key together with iam:CreateRole to prevent roles without a specific permission boundary from being created.