5

I have an S3 bucket that has a structure like this:

top_level_name
  sub_level_1
  sub_level_2
  sub_level_3

I would like to do a blanket Deny of all actions on top_level_name (in order to exclude IAM policies that would otherwise have access to this bucket), and selectively Allow specific users to access their respective sub_levels. Originally I was thinking the policy could look something like:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyTopLevel",
            "Action": [
                "s3:*"
            ],
            "Effect": "Deny",
            "Resource": "arn:aws:s3:::test-bucket/top_level_name/*",
            "Principal": "*"
        },
        {
            "Sid": "AllowSubLevel1",
            "Action": [
                "s3:PutObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::test-bucket/top_level_name/sub_level_1/*",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::12345:user/my_user_account"
                ]
            }
        }
    ]
}

In execution it looks like the Allow is unable to supercede the Deny. Is there a way I can rewrite my bucket policy to implement this pattern?

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
chris.mclennon
  • 966
  • 10
  • 25

1 Answers1

7

No. Deny always overrides Allow.

However, your use-case can be met by if you simply remove your first Deny section. This is because, by default, users have no permission. So, they do not have permission to PutObject in the top level unless a policy specifically allows it.

The second part of your policy grants permissions for lower levels, which is what you want.

If you have other policies that are granting access to the top-level (eg via a * policy), then you will need to re-think your other policies (eg by excluding this bucket from their Allow grant).

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • Thanks @John, this makes a lot of sense. If I have one bucket that is particularly sensitive and should have its privileges be "opt-in" (similar to example), is there a best practice? It sounds like I must either manage every policy used on the IAM level, or potentially split out the bucket into its own protected AWS account? – chris.mclennon Apr 01 '19 at 23:18
  • 1
    Yes, it is quite common to create a separate AWS Account for sensitive data (eg HR or Payroll) and then limit the people who have access to resources in that account. – John Rotenstein Apr 01 '19 at 23:27