I'm writing an IAM policy for my Kubernetes workers. I want them to have read/write access to a certain S3 bucket, no access to other S3 buckets in my account, but read access to any bucket that is publicly readable (such as the s3://1000genomes/
bucket, and other buckets where Amazon or other people have put up public data).
(Whether access is granted or denied to public buckets in my account doesn't matter. If I need to grant access to one I can do that explicitly. But I can't go granting access to every public bucket in the world explicitly.)
I can write a stanza that looks like this to give read access to all buckets in the world:
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::*",
"arn:aws:s3:::*/*"
]
}
I can also write one that grants access to the particular named bucket on my account that I want to allow access to, filling the name in for *
.
But how do I write a policy that denies access to buckets on my account that aren't the named bucket? Or if I take a different approach, how do I write a grant for all buckets not on my account? Is there something I can put between those extra colons that will do this? I've tried using Resource
and NotResource
together, but AWS rejects that.
For reference, my policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::vg-k8s",
"arn:aws:s3:::vg-k8s/*",
]
}
]
}
With that policy in place on my nodes' group, I have no access to s3://1000genomes
from the nodes. To get access to that bucket specifically, I can change it to:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::vg-k8s",
"arn:aws:s3:::vg-k8s/*",
]
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::1000genomes",
"arn:aws:s3:::1000genomes/*"
]
}
]
}
But I need a way to do this so I cover all public buckets, not just those I list, but so I don't cover non-public buckets in my account.