I’d like to restrict public access to some objects we have stored in S3, but show other objects in the same hierarchy of keys. For example, assume I want to make bucketname/* publicly readable. But want to prevent access to bucketname/*/hidden/* for any users that are not expressly given access in IAM.
I can do that with a bucket policy like:
{
"Id": "Policy123",
"Statement": [
{
"Sid": "Stmt123",
"Action": [ "s3:GetObject" ],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucketname/*",
"Principal": {
"AWS": [ "*" ]
}
},
{
"Sid": "Stmt124",
"Action": [ "s3:GetObject" ],
"Effect": "Deny",
"Resource": "arn:aws:s3:::bucketname/*/hidden/*",
"Principal": {
"AWS": [ "*" ]
}
]
}
But that prevents any IAM users/groups I have granted from accessing the hidden objects. Is there a setting for Principal in the second statement that only matches unauthenticated access? Or better yet, is there a way to list only those Principals that should NOT be affected by a policy statement?
According to AWS support, this is currently not possible. Any
Denypolicy overrides a matching (or subset)Allowpolicy and there is no way to deny anonymous access only.A similar effect can be achieved by specifying a private ACL for all objects matching
bucketname/*/hidden/*, but that is not as flexible and must be applied manually.