Trying to isolate IAM user to have AmazonEC2ReadOnlyAccess to only select instances using python boto3

0

Ok so the policy arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess looks like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "elasticloadbalancing:Describe*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:ListMetrics",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:Describe*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "autoscaling:Describe*",
            "Resource": "*"
        }
    ]
}

This works to allow the IAM user to perform most ec2 read functions.

Problem is that this is too permissive. What I need to do is allow all the same functionality as this but ONLY for certain instances. So what I attempted to do is isolate this given a list of instance ids instanceids (using python boto3):

ResourceIds = [ f"arn:aws:ec2:{REGION_NAME}:{AWS_ACCOUNTID}:instance/{iid}" for iid in instanceids]
Ec2ReadOnlyPolicy = {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": ResourceIds
        },
        {
            "Effect": "Allow",
            "Action": "elasticloadbalancing:Describe*",
            "Resource": ResourceIds
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:ListMetrics",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:Describe*"
            ],
            "Resource": ResourceIds
        },
        {
            "Effect": "Allow",
            "Action": "autoscaling:Describe*",
            "Resource": ResourceIds
        }
    ]
}
response = iam_client.put_group_policy(
    PolicyDocument=json.dumps(Ec2ReadOnlyPolicy),
    PolicyName=EC2_RO_POLICY_NAME,
    GroupName=UserGroupName,
)

Problem is that this doesn't seem to allow the user to list instances they have access to:

$ aws ec2 describe-instances
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.

What am I doing wrong?

2 Antworten
2
Akzeptierte Antwort

Hi!

Good question. When crafting IAM Policies, keep in mind that some actions do not support resource-level permissions. If those do not support resource-level permissions, you must specify all resources ("*") in the Resource element of the policy for it to work.

You can determine if actions support resource-level permissions by the actions page (example below). If there are no values in the Resource types column, that means it does not support resource-level permissions.

In your case with DescribeInstances, that action does not support resource-level permissions and must come with all resources specified.

What you can do is separate out the actions that do not support resource-level permissions into 1 block and the ones that do into another block to achieve more granular IAM policies like you're trying to do above.

https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html

jsonc
beantwortet vor 2 Jahren
  • Awesome thanks so much for that I had no clue. Ill give that a try real fast and let you know how that goes.

1

You could also limit access based on tags instead of instance IDs. As an example, below statement gives access to all resources where resource either doesn't have "owner" -tag OR "owner" -tag has the same value as pricipals (=IAM user or role) "owner" -tag has. Untagged resources are accessible for everyone using this policy, but once "owner" tag is attached, only the user (or role) with the same owner -tag value can modify it (including changening the tag).

          - Sid: 'AllowUnlessOwnedBySomeoneElse'
            Effect: Allow 
            Action: '*'
            Resource: '*'
            Condition:
              StringEqualsIfExists:
                'aws:RequestTag/owner': ${aws:PrincipalTag/owner}
                'aws:ResourceTag/owner': ${aws:PrincipalTag/owner}

You can then limit Actions same way you did to EC2s etc. There are also other variables you can use in place of aws:PrincipalTag. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html

Above statement is part of longer story how you can isolate multiple teams working on single account, and yet allow them to create their own IAM policies. https://carriagereturn.nl/aws/iam/policy/boundary/2021/10/07/iambound.html

profile picture
EXPERTE
Kallu
beantwortet vor 2 Jahren
  • Oh dang that looks really promising. Ill give it a try. If this works, it would really help me isolate this even further.

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen