IAM Privileges: How to check what privileges are being used

AWS cli iam privileges

3 min read | by Jordi Prats

When we are working with IAM roles, it's essential to make sure that the permissions we are granting exactly what we need: No more, no less.

The AWS SDK provides a way to check what privileges are being used by a role, group, or user. This can help us to fine-tune the permissions we are granting and remove any unnecessary privileges.

This report will use the activity for the last 400 days (recent activity usually appears within four hours) showing the services and actions that have been used by the role. We can use the AWS CLI to generate this report (or anything with the AWS SDK):

The AWS cli command that we'll need to use to generate this report is: aws iam generate-service-last-accessed-details. We just need to provide the ARN of the IAM resource (user, group, role, or managed policy) we want to audit:

$ aws iam generate-service-last-accessed-details --arn arn:aws:iam::123456789876:role/example-role
{
    "JobId": "2cc926e8-4e95-18f1-2d08-ceba78c9bb61"
}

This is going to return a JobId that we can use to retrieve the report using aws iam get-service-last-accessed-details:

$ aws iam get-service-last-accessed-details --job-id 2cc926e8-4e95-18f1-2d08-ceba78c9bb61
{
    "JobStatus": "COMPLETED",
    "JobType": "SERVICE_LEVEL",
    "JobCreationDate": "2024-10-02T22:19:30.346000+00:00",
    "ServicesLastAccessed": [
        {
            "ServiceName": "Amazon EC2 Auto Scaling",
            "ServiceNamespace": "autoscaling",
            "TotalAuthenticatedEntities": 0
        },
        {
            "ServiceName": "Amazon EC2",
            "LastAuthenticated": "2024-10-02T22:14:23+00:00",
            "ServiceNamespace": "ec2",
            "LastAuthenticatedEntity": "arn:aws:iam::123456789876:role/example-role",
            "LastAuthenticatedRegion": "us-west-2",
            "TotalAuthenticatedEntities": 1
        },
        (...)
    ],
    "JobCompletionDate": "2024-10-02T22:19:30.862000+00:00",
    "IsTruncated": false
}

We'll need to check that the JobStatus is COMPLETED. If it is, we can check the ServicesLastAccessed to see the services that have used that particular service. In the previous example, we can see that the role example-role has used the Amazon EC2 service in the us-west-2 region.

We can get more detailed information by setting the --granularity parameter to ACTION_LEVEL:

$ aws iam generate-service-last-accessed-details --arn arn:aws:iam::123456789876:role/example-role --granularity ACTION_LEVEL
{
    "JobId": "bec926e8-df43-6172-82b1-4d10518634d1"
}
$ aws iam get-service-last-accessed-details --job-id bec926e8-df43-6172-82b1-4d10518634d1
{
    "JobStatus": "COMPLETED",
    "JobType": "ACTION_LEVEL",
    "JobCreationDate": "2024-10-02T22:20:44.422000+00:00",
    "ServicesLastAccessed": [
        {
            "ServiceName": "Amazon EC2 Auto Scaling",
            "ServiceNamespace": "autoscaling",
            "TotalAuthenticatedEntities": 0,
            "TrackedActionsLastAccessed": [
                {
                    "ActionName": "DescribeAutoScalingGroups"
                },
                {
                    "ActionName": "UpdateAutoScalingGroup"
                }
            ]
        },
        {
            "ServiceName": "Amazon EC2",
            "LastAuthenticated": "2024-10-02T22:14:23+00:00",
            "ServiceNamespace": "ec2",
            "LastAuthenticatedEntity": "arn:aws:iam::123456789876:role/example-role",
            "LastAuthenticatedRegion": "us-west-2",
            "TotalAuthenticatedEntities": 1,
            "TrackedActionsLastAccessed": [
                {
                    "ActionName": "AttachVolume"
                },
                (...)
                {
                    "ActionName": "DescribeAvailabilityZones",
                    "LastAccessedEntity": "arn:aws:iam::123456789876:role/example-role",
                    "LastAccessedTime": "2024-09-27T16:43:43+00:00",
                    "LastAccessedRegion": "us-west-2"
                },
                {
                    "ActionName": "DescribeNetworkInterfaces",
                    "LastAccessedEntity": "arn:aws:iam::123456789876:role/example-role",
                    "LastAccessedTime": "2024-10-02T22:14:23+00:00",
                    "LastAccessedRegion": "us-west-2"
                },
                (...)
            ]
        },
        {
            "ServiceName": "Amazon Elastic Kubernetes Service",
            "ServiceNamespace": "eks",
            "TotalAuthenticatedEntities": 0,
            "TrackedActionsLastAccessed": [
                {
                    "ActionName": "UpdateClusterVersion"
                }
            ]
        },
        (...)
    ],
    "JobCompletionDate": "2024-10-02T22:20:44.902000+00:00",
    "IsTruncated": false
}

In this example, we can see that the role example-role has used the Amazon EC2 service in the us-west-2 region. But this time, we can also see the actions that have been used, like DescribeAvailabilityZones and DescribeNetworkInterfaces. This can help us to fine-tune the actions that we really need to allow (for example, if we are granting ec2:* instead of being much more specific).


Posted on 07/10/2024

Categories