New AWS tool recommends removing unused permissions

AWS Identity and Access Management (IAM) policies give customers fine-grained control over who has access to which resources in the Amazon Web Services (AWS) Cloud. This control helps customers enforce the principle of least privilege by granting only the necessary permissions to perform certain tasks. In practice, however, it requires customers to understand what permissions are necessary for their applications to function, which can become a challenge as the scope of the applications grows.

To help customers understand what permissions are not necessary, we launched the IAM Access Analyzer unused access findings at the 2023 re:Invent conference. IAM Access Analyzer Analyzes your AWS accounts to identify unused access and creates a centralized dashboard to report its findings. The results highlight unused roles and unused access keys and passwords for IAM users. For active IAM roles and users, the results provide visibility into unused services and actions.

Related content

New IAM Access Analyzer feature uses automated reasoning to ensure that access policies written in the IAM policy language do not allow unintended access.

To take this service a step further, in June 2024 we launched recommendations to refine unused permissions in Access Analyzer. This feature recommends a refinement of the customer’s native IAM policies that preserves the policy structure while removing the unused permissions. The recommendations not only simplify the removal of unused permissions, but also help customers implement the principle of least privilege for fine-grained permissions.

In this post, we discuss how Access Analyzer policy recommendations suggest policy adjustments based on unused permissions, completing the circle from monitoring overly permissive policies to refining them.

Policy recommendation in practice

Let’s dive into an example to see how policy recommendation works. Assume that you have the following IAM policy associated with an IAM role MyRole:

{
  "Version": "2012-10-17",
  "Statement": [
   {
      "Effect": "Allow",
      "Action": [
        "lambda:AddPermission",
        "lambda:GetFunctionConfiguration",
        "lambda:UpdateFunctionConfiguration",
        "lambda:UpdateFunctionCode",
        "lambda:CreateFunction",
        "lambda:DeleteFunction",
        "lambda:ListVersionsByFunction",
        "lambda:GetFunction",
        "lambda:Invoke*"
      ],
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-lambda"
   },
  {
    "Effect" : "Allow",
    "Action" : [
      "s3:Get*",
      "s3:List*"
    ],
    "Resource" : "*"
  }
 ]
}

The above policy has two policy statements:

  • The first statement allows actions on a function in AWS Lambda, an AWS offering that provides function execution as a service. The allowed actions are specified by specifying individual actions as well as via the wildcard string lambda:Invoke*which allows all actions starting with Invocation in AWS Lambda, such as lambda:InvokeFunction.
  • The second statement allows operations on any Amazon Simple Storage Service (S3) bucket. Actions are specified by two wildcard strings, which indicate that the statement allows actions starting with Get gold List in Amazon S3.

Enabling Access Analyzer for Unused Findings will give you a list of results, each detailing the unused action-level permissions for specific roles. If Access Analyzer e.g. finds any AWS Lambda or Amazon S3 actions that are allowed but not used for the role with the above policy attached, it will show them as unused permissions.

Related content

Amazon Web Services (AWS) is a provider of cloud computing services that has made significant investments in applying formal methods to prove the correctness of its internal systems and provide assurance of correctness to its end users. In this paper, we focus on how we built abstractions and eliminated specifications to scale an AWS access policy verification engine, Zelkova, to be usable by all AWS

The unused permissions define a list of actions that are allowed by the IAM policy but not used by the role. These actions are specific to one namespacea set of resources clustered together and shielded from other namespaces to improve security. Here is an example in Json format showing unused permissions found for MyRole with the policy we attached earlier:

[
 {
    "serviceNamespace": "lambda",
    "actions": [
      "UpdateFunctionCode",
      "GetFunction",
      "ListVersionsByFunction",
      "UpdateFunctionConfiguration",
      "CreateFunction",
      "DeleteFunction",
      "GetFunctionConfiguration",
      "AddPermission"
    ]
  },
  {
    "serviceNamespace": "s3",
    "actions": [
        "GetBucketLocation",
        "GetBucketWebsite",
        "GetBucketPolicyStatus",
        "GetAccelerateConfiguration",
        "GetBucketPolicy",
        "GetBucketRequestPayment",
        "GetReplicationConfiguration",
        "GetBucketLogging",
        "GetBucketObjectLockConfiguration",
        "GetBucketNotification",
        "GetLifecycleConfiguration",
        "GetAnalyticsConfiguration",
        "GetBucketCORS",
        "GetInventoryConfiguration",
        "GetBucketPublicAccessBlock",
        "GetEncryptionConfiguration",
        "GetBucketAcl",
        "GetBucketVersioning",
        "GetBucketOwnershipControls",
        "GetBucketTagging",
        "GetIntelligentTieringConfiguration",
        "GetMetricsConfiguration"
    ]
  }
]

This example shows actions that are not used in AWS Lambda and Amazon S3, but are allowed by the policy we specified earlier.

Neha Rungta

Related content

Rungta had a promising career at NASA, but decided the stars aligned for her at Amazon.

How could you refine the original policy to remove the unused permissions and gain fewer privileges? One option is manual analysis. You can imagine the following process:

  • Find the statements that allow unused permissions;
  • Remove individual actions from these statements by referring to unused permissions.

However, this process can be prone to errors when dealing with large policies and long lists of unused permissions. Also, when there are wildcard strings in a policy, removing unused permissions from them requires careful consideration of what actions should replace the wildcard strings.

Policy recommendation makes this adjustment automatic for customers!

The policy below is one that Access Analyzer recommends after removing the unused actions from the policy above (the figure also shows the differences between the original and revised policies):

{
  "Version": "2012-10-17",
  "Statement" : [
   {
      "Effect" : "Allow",
      "Action" : [
-       "lambda:AddPermission",
-       "lambda:GetFunctionConfiguration",
-       "lambda:UpdateFunctionConfiguration",
-       "lambda:UpdateFunctionCode",
-       "lambda:CreateFunction",
-       "lambda:DeleteFunction",
-       "lambda:ListVersionsByFunction",
-       "lambda:GetFunction",
        "lambda:Invoke*"
      ],
      "Resource" : "arn:aws:lambda:us-east-1:123456789012:function:my-lambda"
    },
    {
     "Effect" : "Allow",
     "Action" : [
-      "s3:Get*",
+      "s3:GetAccess*",
+      "s3:GetAccountPublicAccessBlock",
+      "s3:GetDataAccess",
+      "s3:GetJobTagging",
+      "s3:GetMulti*",
+      "s3:GetObject*",
+      "s3:GetStorage*",
       "s3:List*"
     ],
     "Resource" : "*"
   }
  ]
}

Let’s take a look at what’s changed for each policy statement.

For the first statement, policy recommendation removes all individually listed actions (e.g. lambda:AddPermission), as they appear in unused permissions. Because none of the unused permissions start with lambda: Invocationomits the recommendation lambda:Invoke* untouched.

For the second statement, let’s focus on what happens to the wildcard s3: Few*which appears from the original policy. There are many actions that can start with s3: Fewbut only some of them appear in the unused permissions. Therefore, s3: Few* cannot simply be removed from politics. Instead, it replaces the recommended policy s3: Few* with seven actions to start with s3: Few but are not reported as unused.

Automated reasoning

Related content

Amazon researchers are at the forefront of using math-based logic to provide better network security, access control, and greater reliability.

Some of these actions (e.g. s3:GetJobTagging) are individual, while others contain wildcards (e.g. s3:GetAccess* and s3:GetObject*). A way to replace manually s3: Few* in the revised policy would be to list all the actions that start with s3: Few except the unused ones. However, this would result in an unwieldy policy as there are more than 50 actions to start with s3: Few.

Instead, policy recommendations identify ways to use wildcards to collapse multiple actions that print actions such as s3:GetAccess* gold s3:GetMulti*. Thanks to these wildcards, the recommended policy is concise but still allows all actions starting with s3: Few that are not reported as unused.

How do we decide where to place a wildcard in the newly generated wildcard actions? In the next section, we’ll dive deep into how policy recommendation generalizes wildcard actions to allow only those actions that don’t appear in unused permissions.

A deep dive into how actions are generalized

Policy recommendation is governed by the mathematical principle of “least general generalization”—i.e. to find the least permissible change to the recommended policy that still allows all actions allowed by the original policy. This theorem-supported approach guarantees that the changed policy still allows it everything and only the permissions granted by the original policy that are not reported as unused.

To implement the least general generalization for unused permissions, we construct a data structure known as a sortwhich is a tree whose nodes span a sequence of tokens corresponding to a path through the tree. In our case, the nodes represent prefixes shared between actions, with a special marker for actions reported in unused permissions. By traversing the sort, we find the shortest sequence of prefixes that do not contain unused actions.

The diagram below shows a simplified sort delineation of actions that replaces S3 Get* wildcards from the original policy (we’ve omitted some actions for clarity):

HAIR sort delimitation of actions that can replace Get* wildcard in an IAM policy. Nodes containing unused actions are depicted in orange; the remaining nodes are green.

At a high level, the sort represents prefixes shared by some of the possible actions that start with s3: Few. Its root node represents the prefix Get; child nodes of the root add their prefixes to Get. For example, the named node Multi represents all actions starting with GetMulti.

Elliptic-curve addition.gif

Related content

Automated reasoning and optimizations specific to CPU microarchitectures improve both performance and security for correct implementation.

We say that a node is sure (marked in green in the diagram) if none of the unused actions start with the prefix corresponding to that node; otherwise it is uncertain (indicated in orange). For example the node s3:GetBucket is uncertain because the action s3:GetBucketPolicy is unused. Corresponding to the node pp is safe as there are no unused permissions to start with Get access.

We want our final policies to contain wildcard actions that only correspond to safe nodes, and we want to include enough safe nodes to allow all used actions. We achieve this by selecting the nodes that correspond to the shortest secure prefixes – i.e. nodes that themselves are secure but whose parents are not. As a result, the recommended policy supersedes s3: Few* with the shortest prefixes that do not contain unused permissions, such as s3:GetAccess*, s3:GetMulti* and s3:GetJobTagging.

Together, the shortest safe prefixes form a new policy that, although syntactically similar to the original policy, is the least generalization that results from removing the unused actions. In other words, we have not removed more actions than necessary.

You can find out how to start using policy recommendation with unused access in Access Analyzer. To learn more about the theoretical basis driving policy recommendation, be sure to check out our scientific paper.

Leave a Comment