AWS Security Blog

Introducing New APIs to Help Test Your Access Control Policies

AWS Identity and Access Management (IAM) has added two new APIs that enable you to automate validation and auditing of permissions for your IAM users, groups, and roles. Using these two APIs, you can call the IAM policy simulator using the AWS CLI or any of the AWS SDKs. Use the new iam:SimulatePrincipalPolicy API to programmatically test your existing IAM policies, which allows you to verify that your policies have the intended effect and to identify which specific statement in a policy grants or denies access to a particular resource or action. You can test the effects of new or updated policies that are not yet attached to a user, group, or role by calling the iam:SimulateCustomPolicy API. 

This blog post will walk through validating a specific user’s permissions using the iam:SimulatePrincipalPolicy API. This API takes several parameters that include the policies you want to simulate along with the type of simulation you want to perform. Here is a list:

Policy parameters

  • PolicySourceArn (required): The ARN of a user, group, or role whose policies you want to include in the simulation.
  • PolicyInputList (optional): A list of policies that you want to include in the simulation. This parameter can be used in combination with PolicySourceArn.

Simulation parameters

  • ActionNames (required): A list of API action names to evaluate in the simulation.
  • ResourceArns (optional): A list of ARNs for the AWS resources against which access by the APIs in the ActionNames list is evaluated in the simulation. This parameter defaults to “*” to simulate against all existing and new resources.
  • ContextEntries (optional): A list of context keys and values that are passed to the simulation required for the associated values when a Condition element is used in the policy.

Let’s walk through an example of how to verify permissions for a user by using the AWS CLI. In this example, you will validate that Bob, an IAM user, has permissions to change passwords, but doesn’t have permissions to add policies to users, groups, or roles. To do this, you need to pass two pieces of information into the iam:SimulatePrincipalPolicy API. First, you need the ARN of the IAM user—in this case, Bob—for whom you will simulate the policies. Second, you need the list of actions to verify access. This example will validate the following eight actions.

Actions that enable a user to change passwords:

  1. iam:ChangePassword
  2. iam:GetAccountPasswordPolicy

Actions that enable a user to add managed or inline policies:

  1. iam:PutUserPolicy
  2. iam:PutGroupPolicy
  3. iam:PutRolePolicy
  4. iam:AttachUserPolicy
  5. iam:AttachGroupPolicy
  6. iam:AttachRolePolicy

In this example, you will use the AWS Command Line Interface (CLI) to run the iam:SimulatePrincipalPolicy API. To do so, you can reference the documentation on how to Restrict access to the Policy Simulator APIs. Second, you will need to ensure your command-line credentials are set to the IAM user that has access to call iam:SimulatePrincipalPolicy. If you haven’t already configured the command line, you can do so by running the following commands. Do not forget to replace the fictitious access keys with your user’s access keys.

Linux, OS X, Unix:


After you run these commands, you can run the following command to retrieve the simulation results and then save them to a JSON file.

aws iam simulate-principal-policy –policy-source-arn arn:aws:iam::ACCOUNT:user/Bob –action-names iam:ChangePassWord iam:GetAccountPassWordPolicy iam:PutUserPolicy iam:PutGroupPolicy iam:PutRolePolicy iam:AttachUserPolicy iam:AttachGroupPolicy iam:AttachRolePolicy > simulateOutput.json

If you open simulateOutput.json, you will see if Bob’s policies allow or deny access for each action specified, along with any corresponding policy references. Let’s take a look at the following example output.

1. {
2.    "EvaluationResults": [
3.        {
4.            "EvalDecision": "allowed",
5.            "MissingContextValues": [],
6.            "EvalActionName": "iam:ChangePassword",
7.            "MatchedStatements": [
8.                {
9.                    "SourcePolicyId": 
10.      "user_Bob_68a0527c57ba306fe00ebecc4b3539a0",
11.                    "StartPosition": {
12.                        "Column": 19,
13.                        "Line": 3
14.                    },
15.                    "EndPosition": {
16.                        "Column": 10,
17.                        "Line": 14
18.                    }
19.                }
20.            ],
21.            "EvalResourceName": "*"
22.        },
23.        {
24.            "EvalDecision": "allowed",
25.            "MissingContextValues": [],
26.            "EvalActionName": "iam:GetAccountPasswordPolicy",
27.            "MatchedStatements": [
28.                {
29.                    "SourcePolicyId": 
30.      "user_Bob_68a0527c57ba306fe00ebecc4b3539a0",
31.                    "StartPosition": {
32.                        "Column": 19,
33.                        "Line": 3
34.                    },
35.                    "EndPosition": {
36.                        "Column": 10,
37.                        "Line": 14
38.                    }
39.                }
40.            ],
41.            "EvalResourceName": "*"
42.        },
43.        {
44.            "EvalDecision": "implicitDeny",
45.            "MissingContextValues": [],
46.            "EvalActionName": "iam:PutUserPolicy",
47.            "MatchedStatements": [],
48.            "EvalResourceName": "*"
49.        },
50.        {
51.            "EvalDecision": "implicitDeny",
52.            "MissingContextValues": [],
53.            "EvalActionName": "iam:PutGroupPolicy",
54.            "MatchedStatements": [],
55.            "EvalResourceName": "*"
56.        },
57.        {
58.            "EvalDecision": "implicitDeny",
59.            "MissingContextValues": [],
60.            "EvalActionName": "iam:PutRolePolicy",
61.            "MatchedStatements": [],
62.            "EvalResourceName": "*"
63.        },
64.        {
65.            "EvalDecision": "implicitDeny",
66.            "MissingContextValues": [],
67.            "EvalActionName": "iam:AttachUserPolicy",
68.            "MatchedStatements": [],
69.            "EvalResourceName": "*"
70.        },
71.        {
72.            "EvalDecision": "implicitDeny",
73.            "MissingContextValues": [],
74.            "EvalActionName": "iam:AttachGroupPolicy",
75.            "MatchedStatements": [],
76.            "EvalResourceName": "*"
77.        },
78.        {
79.            "EvalDecision": "implicitDeny",
80.            "MissingContextValues": [],
81.            "EvalActionName": "iam:AttachRolePolicy",
82.            "MatchedStatements": [],
83.            "EvalResourceName": "*"
84.        }
85.    ]
86.    "IsTruncated":false
87. }

First, we will validate that Bob is allowed to change passwords. From the output, we can tell that Bob is allowed to perform the iam:ChangePassword (lines 4 and 6) and iam:GetAccountPasswordPolicy (lines 24 and 26) actions. Looking further at each result, you can see the policy details that are granting access to these actions (line 8-18 and 28-38).

Next, we will validate that Bob cannot add policies to users, groups, and roles. Looking at the results on lines 44, 51, 58, 65, 72, and 79, we can see that Bob shows implicitDeny access to iam:PutUserPolicy, iam:PutGroupPolicy, iam:PutRolePolicy, iam:AttachUserPolicy, iam:AttachGroupPolicy, and iam:AttachRolePolicy.

Based on the output, we have validated that Bob has the expected permissions. If you wish to test another user, you can use the same command and pass in a different user’s ARNs. Furthermore, you can use these APIs with the SDK to validate access periodically by automating the process with a script.

To learn more about the new policy simulator APIs, see our API documentation. If you have questions or suggestions, visit the AWS IAM forum.

– Brigid