Give minimal IAM permissions for S3 actions


3 min read

Give minimal IAM permissions for S3 actions

Why a separate guide on this?

AWS offers the option to generate permissions based on Cloudtrail logs.

That's great for management events, however it doesn't work well for data events. But why?

AWS' policy generation gives you nothing:

And Cloudtrail doesn't record data events in the Event History tab (only Management events).

So when would you even need this?
Here's the specific use case:

"I want to find out what S3 buckets a user accesses and what kind of actions it requires, so I can generate the minimum amount of IAM permissions for the user/users"


  1. You need to have Cloudtrail log already set up. I'll not cover it in this guide (maybe later), but once you have it, let it run for a few days/weeks to allow some actions to be generated. These logs will be saved in an S3 bucket. Keep a note of it.

  2. Go to Cloudtrail => Event history and click on Create Athena table

  3. This will generate you a create table SQL command, which for me was wrong. Make sure you select a Storage location is set to the bucket that holds your data events and make sure on the bottom the LOCATION is correct. (it wasn't for me)

  4. if it's correct, go ahead and create a table, then go to Athena

  5. if not, then copy the create table SQL, go to Athena and try to create a table there pasting in your SQL query with the modified LOCATION property (unfortunately you can't edit the query from Cloudtrail 🤷‍♂️

  6. once there, you can use this SQL to give you the buckets and the actions that are executed on it:

         split_part(resource.arn, '/', 1) AS bucket, 
         eventname AS action
         UNNEST(resources) AS t(resource)
         useridentity.arn = 'arn:aws:iam::123456789012:user/john' 
     ORDER BY 
         bucket, action;
  7. which will result in something like this:

  8. Once you have this, you can generate an IAM policy from them, which will look something like this (you'd need to find the appropriate permission for each action above):

         "Version": "2012-10-17",
         "Statement": [
                 "Effect": "Allow",
                 "Action": [
                 "Resource": [

Further considerations

Now the above gives you an overview of what buckets a user is accessing, but you can take this further. As an example:

  • you can modify the SQL to bring back all users rather than just one

  • you can request the full path to the object that's accessed, creating an even more granular permission set.

Additionally, please note, none of these services are free. Athena, S3 and Cloudtrail all cost money.