Reputation: 1023
I have a bucket that has these prefixes:
Users have access to all bucket by default, but I want to deny access to this specific bucket to all prefixes except those listed above (read/write), for which I tried something like this:
{
"Version": "2012-10-17",
"Id": "BlockReadWriteListAccessExceptUser",
"Statement": [
{
"Sid": "BlockReadWriteAccess",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
},
{
"Sid": "AllowReadWriteAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::mybucket/*_user"
}
]
}
I realized that for get and put, I cannot use conditions, so how can I achieve that?
Upvotes: 1
Views: 1818
Reputation: 1369
jellycsc's answer was super helpful to me, but it's not complete. You must also include an Allow
statement for all resources in your bucket. Otherwise, you won't be able to access any resources.
You then follow that Allow
statement with the Deny
statement provided by jellycsc, which overrides the allow and denies all resources except the specific ones you'd still like to allow.
So the full policy should be the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadWriteAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::mybucket/*"
},
{
"Sid": "BlockReadWriteAccess",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"NotResource": "arn:aws:s3:::mybucket/*_user*"
}
]
}
Upvotes: 0
Reputation: 12289
Your bucket policy will not work because explicit deny always overrides the allows. I want to make this crystal clear. For example, say you want to add an object 999_user
. The object ARN is arn:aws:s3:::mybucket/999_user
, which matches the deny statement with sid "BlockReadWriteAccess". S3 will deny this request right away without even looking at the "AllowReadWriteAccess" statement.
How to achieve the behaviour you want? The policy element NotResource
comes in handy in this case.
{
"Version": "2012-10-17",
"Id": "BlockReadWriteListAccessExceptUser",
"Statement": [
{
"Sid": "BlockReadWriteAccess",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"NotResource": "arn:aws:s3:::mybucket/*_user*"
}
]
}
Upvotes: 1