Struggling to create a bucket policy to white list certain file types. Specifically, I want to allow only image types to be accessible.
I was able to create a blacklist policy like so:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::[my_bucket]/*.exe"
],
"Principal": {
"AWS": "*"
}
}
]
}
WHITELIST ATTEMPT #1:
Problem: this allows all types, not just those listed
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::[my_bucket]/*.jpg",
"arn:aws:s3:::[my_bucket]/*.png",
"arn:aws:s3:::[my_bucket]/*.gif",
],
"Principal": {
"AWS": "*"
}
}
]
}
WHITELIST ATTEMPT #2:
Problem: this ends up denying all files
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::[my_bucket]/*"
],
"Principal": {
"AWS": "*"
}
},
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::[my_bucket]/*.jpg",
"arn:aws:s3:::[my_bucket]/*.png",
"arn:aws:s3:::[my_bucket]/*.gif",
],
"Principal": {
"AWS": "*"
}
}
]
}
Your whitelist bucket policy #1 is correct. The reason it is allowing all file types could be your IAM policy allows all file types for the user. Make sure the IAM policy attached to the user does not have S3FullAccess
In accordance with the principle of least-privilege, decisions default
to DENY and an explicit DENY always trumps an ALLOW. For example, if
an IAM policy grants access to an object, the S3 bucket policies
denies access to that object, and there is no S3 ACL, then access will
be denied. Similarly, if no method specifies an ALLOW, then the
request will be denied by default. Only if no method specifies a DENY
and one or more methods specify an ALLOW will the request will be
allowed.
Related
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>"
]
}
}
}
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.
I want to share my bucket (sourcebucket) with an IAM User (testuser) for a limited time window. Does AWS provide any bucket policy so that I can share my bucket objects with the IAM User for a limited time frame?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678910:user/testuser"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::sourcebucket/*",
"arn:aws:s3:::sourcebucket"
]
}
]
}
Does AWS provide any bucket policy so that I can share my bucket objects with the IAM User for a limited time frame?
Yes.
Check the DateGreaterThan and DateLessThan conditions and the aws:CurrentTime condition key. Here's an example, using the policy in your question as a base:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DelegateS3Access",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678910:user/testuser"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::sourcebucket/*",
"arn:aws:s3:::sourcebucket"
],
"Condition": {
"DateGreaterThan": {"aws:CurrentTime": "2020-04-01T00:00:00Z"},
"DateLessThan": {"aws:CurrentTime": "2020-06-30T23:59:59Z"}
}
}
]
}
Here are some useful links:
AWS Global Condition Context Keys: aws:CurrentTime
AWS: Allows Access Within Specific Dates
I hava an S3 Bucket ("myBucket"), to which only a user has access, let's call it "s3user". I have an IAM policy attached to this user as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::myBucket"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:GetObjectVersion"
],
"Resource": "*"
}
]
}
I attached this IAM Policy to user "s3User", granting read-only access to "myBucket". So far so good.
Now, I added a second policy, but now not an IAM policy but an S3 Bucket Policy, as follows:
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::myBucket/*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"1.2.3.4/27",
"2.3.4.1/28",
"5.6.7.8/29"
]
}
}
}
]
}
I expected that this explicit deny will deny all requests not coming from the specified source IP ranges. But, it is still letting me list the contents of the bucket from other IPs. It seems as if the bucket policy had no effect at all.
According to this AWS S3 article, when you have multiple policies, they are all applied and explicit denies have precedence over explicit allows, so I think this should be working, but it isn't.
Any ideas why I'm not able to deny requests to a bucket based on sourceIP addresses?
Thanks!
You should update your Deny policy to include operations that are performed on the bucket itself, rather than its content (/*):
{
"Version": "2012-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "DenyOutsideIPfromBucket",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:GetObjectVersion"
],
"Resource": ["arn:aws:s3:::myBucket/*", "arn:aws:s3:::myBucket"],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"1.2.3.4/27",
"2.3.4.1/28",
"5.6.7.8/29"
]
}
}
}
]
}
Of course, if the only users with access to the bucket are the ones with the IAM policy, you could simply add a IpAddress condition on the original IAM policy, so they can only use the bucket from the given set of IP addresses. This would avoid the need for a Deny policy.
My buckets folders are private, but when I copy the URL of an individual object into a browser (when I'm logged out), I can still download/view the file.
How can I prevent this?
Here's my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::my-bucket/backup/*"
}
]
}
What I am trying to achieve: make every folder private except for 2 folders called media and static (which I want public read access for).
In your policy your are specifically telling it allow anonymous public GET Access.
You have to change it to something like below.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::ACCOUNT_ID:user/USERNAME_A",
"arn:aws:iam::ACCOUNT_ID:user/USERNAME_B",
"arn:aws:iam::ACCOUNT_ID:user/USERNAME_C",
"arn:aws:iam::ACCOUNT_ID:role/ROLE_A",
"arn:aws:iam::ACCOUNT_ID:role/ROLE_B",
"arn:aws:iam::ACCOUNT_ID:role/ROLE_C"
]
},
"Resource": [
"arn:aws:s3:::BUCKET_NAME",
"arn:aws:s3:::BUCKET_NAME/*"
]
}
]
}
Refer more policy examples here.
I think you are looking for something like this.
{
"Version":"2012-10-17",
"Statement": [
{
"Sid": "AllowAllS3ActionsInOtherFolders",
"Action":["s3:*"],
"Effect":"Allow",
"Resource": ["arn:aws:s3:::my-bucket"],
"Condition":{"StringLike":{"s3:prefix":
[
"backup/media/*"
"backup/static/*"
]
}
}
}
]
}
Please refer this Grant Access to User-Specific Folders in an Amazon S3 Bucket for more details.
This policy grants public GetObject access to the two folders.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadAccess",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::jr-enc/media/*",
"arn:aws:s3:::jr-enc/static/*"
],
"Principal": "*"
}
]
}
Note that GetObject only grants access to access/download an object. It does not give permission to list the contents of the bucket/folders.
My goal is to create exclusive access to a bucket for one IAM user, and to maintain that exclusivity easily as new iam users and groups are added. The user is outside of my control and has a managed policy attached to it:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "FullTestBucketS3Access",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::test",
"arn:aws:s3:::test/*"
]
}
]
}
I have applied a bucket policy to the bucket that needs to exclude all users except one:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::111111111111:root",
"arn:aws:iam::111111111111:user/myuser"
]
},
"Action": [
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::test",
"arn:aws:s3:::test/*"
]
}
]
}
I am finding that the mask provided by the NotPrincipal part of the deny statement is not working. All users are denied the ability to take the action specified in the deny policy. What should I be looking at to work this out?