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