The AWS IAM Simulator is a tool that enables you to test the effects of IAM access control policies. This tool helps when you find yourself manually performing actions to test a policy. The tool can simulate actions for any IAM entity or resource and for unique sets of conditions. This post will show you how to test an S3 bucket policy attached to a bucket in your AWS account.

General Steps for Testing a Policy

AWS provides a User Guide for the policy simulator. Let’s step through an example here.  We will test a resource-based policy rather than one attached to an IAM user, group, or role. First, attach a policy to an S3 bucket and then check that the simulator is in the Existing Policies mode.  The policy used in this example is available in the QualiMente tf_s3_bucket repository, secure-by-default.json.

Mode: Existing Policies has been selected from the drop down in the gray header

Begin by selecting the S3 service and then the actions that you’d like to test. We’ll use GetObject, ListBucket, and PutObject for this example.

Amazon S3 and three actions have been chosen

Drop down each action to reveal the object input then paste in the appropriate bucket ARN. Under the Global Settings and PutObject tabs, you can see inputs for condition keys. The conditions you see here come from the policy we’ll be testing which you’ll see later on.

Policy condition key fields have appeared

Testing a policy’s behavior is as easy as changing the blank input values to values you expect. Next select a user, group, or role using the column on the left-hand side of the console. We can run identical tests for unique IAM entities by selecting a new entity in that column. Once you’ve given the condition keys a value and chosen an entity, click Run Simulation. As you’ll soon see, the result is a permission statement saying the action was allowed or denied.

Users, Groups, and Roles drop down shown on the left

Testing secure-by-default

The following S3 policy, secure-by-default, should do three things:

  • require https for secure transport
  • require a particular encryption method on disk
  • and permit only roles, groups, and users within the account

The <bucket-name> & <account-ID> are in place of the actual bucket name and account ID. You’ll want to use a complete JSON policy document for your simulation. Notice that three of the policy’s statements have conditions. Some of these apply to all actions and one applies only to the PutObject action. This is where the simulator finds global and specific condition keys like we saw earlier.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyInSecureCommunications",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::<bucket-name>",
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        },
        {
            "Sid": "DenyIncorrectEncryptionHeader",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<bucket-name>/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "AES256"
                }
            }
        },
        {
            "Sid": "DenyUnEncryptedObjectUploads",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<bucket-name>/*",
            "Condition": {
                "Null": {
                    "s3:x-amz-server-side-encryption": "true"
                }
            }
        },
        {
            "Sid": "PermitOnlyRolesWithinAccount",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<account-id>"
            },
            "Action": "*",
            "Resource": "arn:aws:s3:::<bucket-name>"
        }
    ]
}

Case #1: Unencrypted transport, unencrypted storage

For the first test case, we’ll supply a username and set aws:securetransport to false. Leave s3:x-amz-server-side-encryption blank for now. The simulator will correctly deny all three actions. The permission column shows the number of policy statements that denied each action. The total for this case is four because the policy has four statements, and each one behaved as we expected. Now let’s try changing one field at a time, so each statement passes.

Note: The simulation will fail if you leave any condition keys for Global Settings blank. But, you can leave condition keys for specific actions blank without causing errors.

Result of Case #1

Case #2: Require secure transport

For this case, we’ve only changed the aws:securetransport field from false to true. The GetObject and ListBucket actions are now allowed. But the PutObject action is still denied. Next we can try specifying an encryption type.

Result of Case #2

Case #3: Require encrypted storage

Here we’ve changed the s3:x-amz-server-side-encryption field from being empty to not-null. The policy is still denying the user permission to perform the PutObject action. But only one policy statement is now failing instead of two statements. This suggests that the policy will enforce encryption, but it must be the matching type.

Result of Case #3

Case #4: Require AES256 storage encryption

Let’s change the specified encryption type to AES256. Now all three actions we chose to test are allowed. The simulator console shows us that it’s no longer referencing the resource policy. Instead the user’s attached policy, AdministratorAccess, is being checked now. These test cases reflect that the secure-by-default policy is behaving as we expected.

Result of Case #4

Further Use

We’ve now seen how to test a resource-based policy using the IAM Policy Simulator. Yet, this tool has even more functions than that. The left side of the console lists every user, group, and role in your AWS account. Selecting different entities from this column will let you test their attached policies. Additionally, you can change the simulator mode from Existing Policies to New Policy. This allows you test the behavior of policies that aren’t already in production.

Users, Groups, and Roles drop down shown on the left

There are more options for those seeking greater efficiency in testing IAM policies. AWS has also provided instructions to use this tool from their CLI and API. This would allow you to script and rerun these simulations for each new change to a policy document.

 

References