Test an S3 bucket policy using the AWS IAM Simulator

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 IAM simulator can simulate actions for any IAM principal, resource, and policy conditions. This tutorial shows how to test an S3 bucket policy attached to a bucket in your AWS account using the IAM simulator.

Ok, let’s test accessing an S3 bucket under several conditions.

General Steps for Testing a Policy

AWS provides a User Guide for the policy simulator.  Let’s step through an example here.  We will focus our testing on an S3 bucket resource policy rather than policies attached to an IAM user, group, or role. The testing process includes:

  1. Configure the bucket and policies to test
  2. Configure the IAM policy simulator
  3. Execute policy tests with specific actions & conditions

The IAM policy simulator works best with a resolution 1200×800 or better.

Configure the IAM Simulator

Now let’s navigate to the policy simulator and begin configuration.

Configure IAM Simulator mode and principal

First verify the simulator is in the Existing Policies mode in the gray header.

Then select the IAM user or role you’d like to execute the tests as from the controls on the left.  This tutorial uses an IAM role with the AdministratorAccess IAM policy to demonstrate that resource policies can limit what principals with full access can do.

Now select the S3 service and then the actions that you’d like to test. We’ll use GetObject, ListBucket, and PutObject for this example.  The ‘Select actions’ control needs at least 800px (square), so use a display with high resolution.  Here’s what the simulator looks like with roles and service actions configured:

IAM role and service actions configured in Simulator

Next select each action to reveal the object input then paste in appropriate bucket resource ARNs for your tests. The Resource Type column tells you whether the action expects a bucket or a bucket object ARN.   The S3 bucket name for this example is test-policy-simulation bucket, so the bucket ARN is arn:aws:s3:::test-policy-simulation.  Specifying that bucket ARN instructs the simulator to test against the bucket.  Specifying arn:aws:s3:::test-policy-simulation/* tests against the objects in the bucket.

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 appear in IAM simulator

Now let’s test the policy’s behavior. 

Change the blank policy condition input values to those you want to test click Run Simulation. As you’ll soon see, the result is an access evaluation statement reporting whether the action was allowed or denied.

You can run additional tests for other IAM entities by clicking ‘Back’ and selecting a new entity in the IAM principal column.

Let’s see how this works by verifying the bucket policy enforces encryption requirements.

Testing the example S3 bucket policy

We’ll use the IAM simulator to show the example S3 bucket policy (GitHub gist) below does two things:

  • requires https for secure transport
  • requires a particular encryption method on disk

If you test with this example’s policy, change the <bucket-name> & <account-ID> to your own. This gives you a complete JSON policy document for your simulation.

Note that:

  1. AllowAllPrincipalsWithinAccount allows any IAM user or role in the account to perform any action on the bucket — fine for demoing the simulator, but definitely not a least-privilege policy
  2. the three Deny* statements use global and s3 policy conditions

Some statements apply to all actions and one applies only to the PutObject action.  The simulator finds the global and specific condition keys we saw earlier in policy statements.

Example: Bucket Policy

Case #1: Unencrypted transport, unencrypted storage

For the first test case, we’ll supply a username and set both aws:securetransport and s3:x-amz-server-side-encryption to false

Both of these conditions are set automatically by AWS when a  real action is performed.  However, the simulator ignores policy condition keys with unset values.  Since we are executing a negative test case for unencrypted transport and storage, we need to set them to false.

The simulator correctly shows all three actions are denied:

Test Case #1 Results: Unencrypted transport, unencrypted storage

The permission column shows the number of policy statements that denied each action. The total for this case is four because the bucket policy’s three Deny statements cover both transport and storage.

The simulator shows you which statement in which policy allowed or denied an action.  Clicking on ‘Show statement’ for why GetObject was denied reveals:

Navigate to the statement that denied access

GetObject and ListObject are denied by the DenyInsecureCommunications statement. The PutObject action was denied by DenyStorageWithoutKMSEncryption because it was false, not aws:kms.

Now let’s try changing one field at a time, so each statement passes.

Case #2: Encrypted transport, unencrypted storage

For this case, change the aws:securetransport field from false to true, then rerun the simulation.

Test Case #2 Results: Encrypted transport, unencrypted storage

The GetObject and ListBucket actions are now allowed.

The PutObject action is still denied by the DenyStorageWithoutKMSEncryption statement. Let’s explore that now.

Case #3: Encrypted transport, incorrect encryption storage

Change the s3:x-amz-server-side-encryption service policy condition from false to AES256. The value false is not a real AWS encryption type, but we had to specify a value so the simulation process would not ignore the encryption policy condition. Rerun the simulation with a valid, but incorrect AWS encryption type:

Test Case #3 Results: Incorrect storage encryption type

Case #4: Encrypted transport, (correctly) encrypted storage

Finally, change the specified encryption type to aws:kms and rerun the simulation. 

Test Case #4 Results: Encrypted transport, KMS-encrypted storage

Now all three actions we chose to test are allowed!

The simulator console no longer references the resource policy for its permission decision. Instead access is granted by the role’s attached AdministratorAccess policy.

These test case results verify that the secure bucket policy behaves as expected.

Next Steps

We’ve now seen how to test a resource-based policy using the IAM Policy Simulator.

The IAM policy simulator tool has many more functions. The left side of the console lists every user, group, and role in your AWS account. Selecting different principals from this column will let you test their attached policies, as well as attach and detach particular policies.  You can even create and test new policies using the simulator’s ‘New Policy’ mode.

There are more options for those seeking greater efficiency in testing IAM policies. You can simulate access using the AWS CLI and API. This would allow you to script and rerun these simulations for each new change to a policy document.

Simulating access for all IAM users, roles, and resources in your account is not easy, but k9 Security can help. 

k9 analyzes access granted by your AWS security policies nightly, and publishes a report that is easy to understand to your own secure inbox in S3 (check it out!).

Contact Us

Please contact us with questions or comments. We’d love to discuss AWS security with you.