Reputation: 134
Can you write an s3 bucket policy that will deny access to all principals except a particular IAM role and AWS service role (e.g. billingreports.amazonaws.com).
I have tried using 'Deny' with 'NotPrincipal', but none of the below examples work as I don't think the ability to have multiple types of principals is supported by AWS?
This allows you to save the policy but locks out the bucket (warning: only root user can then update policy to unlock)
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::<account_id>:root",
"arn:aws:iam::<account_id>:role/specialBillingRole"
],
"Service": "billingreports.amazonaws.com"
}
Therefore I am trying to use conditions but can't find the right combinations that will work. Here is an example policy.
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "billingreports.amazonaws.com"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::<account_id>:role/specialBillingRole",
"billingreports.amazonaws.com",
"<account_id>"
]
}
}
}
]
}
UPDATED the question as per some comment suggestions.
2nd UPDATE Also tried the below, which still gives access to all roles/users in the account (can't use wildcards in the Principal
).
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<account_id>:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
],
"Condition": {
"ArnNotEquals": {
"aws:PrincipalArn": [
"arn:aws:iam::<account_id>:role/specialBillingRole",
"<account_id>"
]
}
}
}
Upvotes: 7
Views: 11565
Reputation: 404
You can certainly create a bucket policy that grants access only to a service role and an IAM role, but to be clear, a service role will still begin with "arn:aws:iam:::role...".
Are you instead trying to create a bucket policy that grants access both to a particular service and a service role? I'm asking because if you have a role created with billingreports.amazonaws.com as its trusted entity, and if that role is what's intended to access the bucket, then you do not need to list the service separately in your bucket policy (if the scenario is as I imagine).
Please do note, also, that you can indeed use wildcards with the principal, combined with a condition - I do so all the time (see my example policy below). When I want to restrict bucket access to a specific role, I simply include an Allow statement with a Principal of just the role I want to allow, and then a Deny statement with a Principal of "AWS": "*", followed by a condition, like so:
{
"Version": "2008-10-17",
"Id": "PolicyScopedToSecurity",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[accountID]:role/[roleName]",
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::[bucketName]",
"arn:aws:s3:::[bucketName]/*"
]
},
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::[bucketName]",
"arn:aws:s3:::[bucketName]/*"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::[accountID]:role/[roleName]",
"[accountID]"
]
}
}
}
]
}
If you truly need the service itself to access the bucket, the solution will be slightly different. My response assumes the service role needs access.
Upvotes: 3