AWS Security Blog

An In-Depth Look at the IAM Policy Simulator

by Ben Brauer | on | in Best Practices, How-to guides | | Comments

This week’s guest blogger, Ajith Ranabahu, Software Development Engineer on the AWS Identity and Access Management (IAM) team, presents an in-depth look at the IAM policy simulator.


Many of you have asked about how to author and troubleshoot access control policies. To help with this task, last year we launched the policy simulator, which makes it easier for you to test the effects of policies before committing them into production.

I’ve broken this blog post into three use cases that demonstrate how to use different aspects of the policy simulator.  For each use case, I also introduce how to troubleshoot more advanced policy options.

This post assumes basic familiarity with the policy simulator. For a quick primer, check out the getting started video and the policy simulator announcement

Also, a small announcement! Just last week, we added a new way to launch the policy simulator. If you’re working with a user or group in the IAM console and you’re in the Permissions tab, there’s a new Simulate Policy link that will take you right to the policy simulator, with the user’s or group’s policy already filled in:

Screenshot showing the Simulate Policy link

And now on to the use cases.

Use Case 1: Permission troubleshooting

This use case illustrates how you can use the policy simulator to pinpoint the source of why your policy isn’t having the intended effect. For example, Bob is a new employee at Example Corp., which has created IAM groups for its administrators, accountants, and contractors. Bob is an administrator so he has been given IAM user credentials, in accordance with AWS best practices, and permissions that should allow him to manage all AWS services and resources. However, he finds that he cannot call IAM APIs even though he has been granted administrator access. Let’s figure out how to fix his permissions issue.

The policy simulator simplifies this troubleshooting process. To accomplish this, select Bob, choose the AWS actions to verify (in this case IAM actions), and run a simulation, the results of which are shown in Figure 1.

Screenshot showing results of running a simulation

Figure 1: A simple simulation shows that Bob is indeed denied access to IAM actions.

The tool shows the list of permissions results (allow or deny) and that Bob is subject to two policies: “Administrator-permissions” and “Developer-permissions. If you click the link for “List Contributing statements”, revealing the policy statement responsible for each result, then click “Show statement”, you can see that the group policy “Developer-permissions” enforces a deny on IAM actions, shown in Figure 2. It looks like Bob was incorrectly assigned membership in a non-admin group.

Screenshot showing the group policy “Developer-permissions” enforcing a deny on IAM actions

Figure 2: Clicking on “Show statement” expands and highlights the matched statement.

In this case, simply removing Bob from the group resolves the issue. Remember that the policy simulator is a sandbox environment, so you’ll have to make this change using the AWS Management Console, CLI, or API.

Use Case 2: Applying Access Control Conditions

Now let’s look at a slightly more complex case involving policy conditions, which are elements of a policy that specify when the policy takes effect.

Assume that Harry is a temporary contractor who works from a specific workstation, should have access to a specific S3 bucket, but only for the two months when he is working on the project. Such restrictions are possible by using condition keys that enforce date and time (aws:CurrentTime) and IP address (aws:SourceIp). Harry’s manager, Jim, wants to validate this policy before Harry starts work. In this case, Jim is testing the following policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::Example-corp-reports/*"
            ],
            "Condition": {
                "DateLessThan": {
                    "aws:CurrentTime": "2013-12-01"
                },
                "DateGreaterThan": {
                    "aws:CurrentTime": "2014-01-31"
                },
                "IpAddress": {
                    "aws:SourceIp": "10.1.20.20/24"
                }
            }           
        }
    ]
}

Figure 3: IP address and date based access restriction policy for a contractor.

The policy simulator automatically identifies the condition keys required for a given set of policies and then brings up a UI for the users to enter values for each key. When Jim runs the simulation, he sees that Harry is still denied access to the S3 bucket even though Jim entered a valid IP address and a date within the expected time period.

Screenshot showing that even for a date when Harry should have access, this policy does not grant him access

Figure 4: Even for a date when Harry should have access, this policy does not grant him access!

Upon close inspection of the conditions, it becomes clear that the date conditions are switched.

Screenshot showing that the date conditions are switched

Figure 5: The date conditions are switched – they should be the other way around.

Correcting the conditions in the policy makes it work as intended (see Figure 6).  The corrected policy in this case is illustrated in Figure 7.

Screenshot showing that now the permissions are working as intended

Figure 6: Correcting the policy and running the simulation again shows that now the permissions are working as intended.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": [
                "arn:aws:s3:::Example-corp-reports/*"
            ],
            "Condition": {
                "DateGreaterThan": {
                    "aws:CurrentTime": "2013-12-01"
                },
                "DateLessThan": {
                    "aws:CurrentTime": "2014-01-31"
                },
                "IpAddress": {
                    "aws:SourceIp": "10.1.20.20/24"
                }
            }           
        }
    ]
}

Figure 7: Corrected policy to enable a contractor access an S3 bucket from a specific workstation within a specified time period.

Try copying the policy in Figure 7 into the policy simulator and running it on one of your own S3 buckets. Remember that when you simulate policies involving condition keys, you must first populate all the relevant fields in the simulation settings.

Use Case 3: Troubleshooting generalized policies that use policy variables

The third use case shows how you can use the IAM policy simulator to test policies that use policy variables. Policy variables make it easier to define general policies for individualized access control without explicitly listing all the components of the policy. For example, you can craft a policy where all IAM users in your organization have access to S3 “home directories”, i.e. folders named based on their IAM username.

The example policy below uses the ${aws:username}variable to allow users access to any S3 object in the Example-corp-reports bucket that contains a prefix that matches their username.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
              "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::Example-corp-reports"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "${aws:username}"
                    ]
                }
            }
        },
        {
             "Effect": "Allow",
             "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::Example-corp-reports/${aws:username}*"
            ]
        }
    ]
}

Figure 8: Variable-based policy used in giving users access to their reports in a given bucket.

Simulating this policy shows that the resource “report.pdf” in the ‘Bob’ folder is only accessible to Bob and not Alice.

Screenshot showing that report.pdf is accessible to Bob only--and not Alice

Figure 9: Running a simulation using Bob/report.pdf as the resource and against IAM user Bob shows that Bob has access to this report as expected.

Screenshot confirming that Alice has no access to report.pdf

Figure 10: Running the same resources with Alice shows that she has no access to this resource.

However, when simulating through the possible list of users, the tool shows that Bob can also access Bobby’s folder as well. That’s because this policy with the “${aws:username}*” syntax gives access to S3 objects of other users when one user name begins with the characters of another user’s name (the first 3 characters of “Bobby” is “Bob”).

Screenshot showing Bob can access Bobby's reports

Figure 11: Using Bob as the user against the Bobby’s reports show that Bob can access Bobby’s reports.

In this case, the problem can be resolved by inserting a “/” after the policy variable, but before the wildcard character (“${aws:username}“). This will allow Bob to view all objects in the S3 Example-corp-reports bucket that have a prefix that matches his name.

Screenshot showing that including an ‘/’ after the user name ensures that users only have access to the folders by their own user name

Figure 12: Fixing the policy to include an ‘/’ after the user name ensures that users only have access to the folders by their own user name.

The complete corrected policy is illustrated in Figure 13.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
              "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::Example-corp-reports"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "${aws:username}"
                    ]
                }
            }
        },
        {
             "Effect": "Allow",
             "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::Example-corp-reports/${aws:username}/*"
            ]
        }
    ]
}

Figure 13: The corrected policy, granting access only to prefixes that start with a username.

I hope these use cases clarify how the policy simulator can help you author and troubleshoot policies in your AWS environment. Have a comment or suggestion to improve the policy simulator? Please post it below or start a thread on the IAM forum.

– Ajith