Search code examples
amazon-web-servicesaws-lambdaamazon-iamaws-secrets-manager

Attribute Based Access Controll issue for AWS Lambda with IAM policy


I am trying to follow this article for Secret Manager and tried applying attribute based access controll (ABAC) for AWS Lambda by using this user role policy linkage:

  1. Create IAM user
  2. Assign a role to this IAM user
  3. Role is assigned an ABAC policy for lambda.

currently my ABAC policy for Lambda usage for different users in a project is as follows:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "LambdaPolicyForProject",
            "Effect": "Allow",
            "Action": [
                "cloudformation:DescribeStacks",
                "cloudformation:ListStackResources",
                "cloudwatch:GetMetricData",
                "cloudwatch:ListMetrics",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "kms:ListAliases",
                "iam:GetPolicy",
                "iam:GetPolicyVersion",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:ListAttachedRolePolicies",
                "iam:ListRolePolicies",
                "iam:ListRoles",
                "logs:DescribeLogGroups",
                "lambda:Get*",
                "lambda:List*",
                "states:DescribeStateMachine",
                "states:ListStateMachines",
                "tag:GetResources",
                "xray:GetTraceSummaries",
                "xray:BatchGetTraces"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/accessproject": "${aws:PrincipalTag/accessproject}",
                    "aws:ResourceTag/accessteam": "${aws:PrincipalTag/accessteam}",
                    "aws:ResourceTag/costcenter": "${aws:PrincipalTag/costcenter}"
                }
            }
        }
    ]
}

This does not work for a user when the costcenter, accessteam, accessproject tags are similar for both IAM user and lambda.

However, it works when I remove the condition in the above policy (this shows IAM is able to access lambda policy).

Can I know what I am missing from the tutorial above? I did cross check all tags for lambda, policies and IAM users, and they are same as per the docs.


Solution

  • The issue seems to be in the Actions you defined. According to the tutorial you followed:

    [...] see Actions, Resources, and Condition Keys for AWS Secrets Manager. That page shows that actions performed on the Secret resource type support the secretsmanager:ResourceTag/tag-key condition key. Some Secrets Manager actions don't support that resource type, including GetRandomPassword and ListSecrets.

    Have a look at actions, resources, and condition keys for AWS services and for each service make sure the action supports the aws:ResourceTag/${TagKey} condition. I didn't go through all the permissions but already the CloudWatch actions GetMetricData and ListMetrics do not support the aws:ResourceTag/${TagKey} condition. Same goes for ec2:DescribeSecurityGroups, ec2:DescribeSubnets, ec2:DescribeVpcs, and probably a few more.

    You must create additional statements to allow those actions i.e:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "LambdaPolicyForProject",
                "Effect": "Allow",
                "Action": [
                    "cloudformation:DescribeStacks",
                    "cloudformation:ListStackResources",
                    "kms:ListAliases",
                    "iam:GetPolicy",
                    "iam:GetPolicyVersion",
                    "iam:GetRole",
                    "iam:GetRolePolicy",
                    "iam:ListAttachedRolePolicies",
                    "iam:ListRolePolicies",
                    "iam:ListRoles",
                    "logs:DescribeLogGroups",
                    "lambda:Get*",
                    "lambda:List*",
                    "states:DescribeStateMachine",
                    "states:ListStateMachines",
                    "tag:GetResources",
                    "xray:GetTraceSummaries",
                    "xray:BatchGetTraces"
                ],
                "Resource": "*",
                "Condition": {
                    "StringEquals": {
                        "aws:ResourceTag/accessproject": "${aws:PrincipalTag/accessproject}",
                        "aws:ResourceTag/accessteam": "${aws:PrincipalTag/accessteam}",
                        "aws:ResourceTag/costcenter": "${aws:PrincipalTag/costcenter}"
                    }
                }
            },{
                "Sid": "LambdaPolicyForProjectNoTags",
                "Effect": "Allow",
                "Action": [
                    "cloudwatch:GetMetricData",
                    "cloudwatch:ListMetrics",
                    "ec2:DescribeSecurityGroups",
                    "ec2:DescribeSubnets",
                    "ec2:DescribeVpcs"
                ],
                "Resource": "*"
            }
        ]
    }
    

    Once you have a working policy, please familiarize yourself with the IAM best practices as the use of wildcard resouce access should be avoided whenever possible (principle of granting least privilege).