amazon-web-servicesamazon-s3amazon-policy

Is it possible to have an "Allow" effect override a "Deny"?


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?


Solution

  • 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).