S3 bucket policy & IAM policy

David Cheong
5 min readAug 28, 2020

--

AWS S3 provide a lot of flexibility on the permission control, you can either attach the policy on the IAM user, buckets or use the pre-canned ACL. That’s no right or wrong way to attach the policy on either IAM or resource level, it’s depend on your use case and you can use both side of policy to compliment each other.

To create the bucket policy

  1. Go to the respective bucket where you want to add the policy
  2. Click on Permissions,
  3. Select the bucket policy. You will get a text area where you can enter your policy into.

If you not familiar with the bucket policy syntax, you can just use the policy generator at the bottom of the page to help you on this, or you can just search of sample policy on the internet.

To add the policy to the IAM user

  1. Go to the IAM console
  2. on the left menu, click on users
  3. Choose the user that you wish to add the policy into
  4. On the user details page, choose the Permission tab and than choose Add inline policy
  5. Choose the JSON tab
  6. Copy the following policy and paste it into the policy text field

It’s always recommended to use the latest policy version which is “2012–10–17” in your policy JSON, this is because if you not specify the version number, AWS will use the old version as a default “2008–10–17” which may have some limitation.

In the article, I will share few of the S3 bucket policy as well as IAM policy which are commonly use for most of the public or private bucket.

1. Only allow HTTPS access policy

By default, S3 supported both HTTP and HTTPS request. In order to disable the access using HTTP but only allow HTTPS, we can create the rule to deny the http access with the bucket policy by adding the condition where “aws:SecureTransport” is false. This will explicitly deny any none https request by accessing the bucket and it’s content.

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSLRequestsOnly",
"Action": "s3:*",
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::awsexamplebucket",
"arn:aws:s3:::awsexamplebucket/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
},
"Principal": "*"
}
]
}

In contrast, you may using the allow s3:GetObject policy with the condition “aws:SecureTransport”:”True” which may have the same effect. This statement allow any user to access the s3:GetObject for all object if its request uses HTTPS, but try to avoid this unless there is a special purpose for your own use case. We should always use deny to explicitly block the none https request.

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSLRequestsOnly",
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::awsexamplebucket",
"arn:aws:s3:::awsexamplebucket/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "True"
}
},
"Principal": "*"
}
]
}

2. IP whitelisting policy

To allow only the certain IP to access the s3 bucket, just add the condition to check on the IPAddress “aws:SourceIP” is from the list of CIDR range only.

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSLRequestsOnly",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::awsexamplebucket",
"arn:aws:s3:::awsexamplebucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"11.11.11.11/32",
"22.22.22.22/32"
]
}
},
"Principal": "*"
}
]
}

3. IP blacklisting policy

In contrast, to blacklist the IP, use the condition to check NotIpAddress “aws:SourceIp” with the CIDR range

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSSLRequestsOnly",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::awsexamplebucket",
"arn:aws:s3:::awsexamplebucket/*"
],
"Condition": {
"NotIpAddress": {
"aws:SourceIp": [
"11.11.11.11/32",
"22.22.22.22/32"
]
}
},
"Principal": "*"
}
]
}

4. Allow IAM user access to a folder in a bucket

This is the policy that attach to the IAM user, so that’s no principal needed for the policy.

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow only own folder",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket/Alice/*"
}
]
}

5. Allow IAM user access to their own bucket with their own username

To use the AWS variable “${aws:xxxxxxx}” in the policy, the version must specific “2012–10–17”, if you not specific the version number, the default version of “2008–10–17” will be use which may not work in this case.

In the following policy, we assume that you already have the folder under the bucket name awsexamplebucket

awsexamplebucket 
Alice/
Bob/
Criss/
{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow only username folder",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket/${aws:username}/*"
}
]
}

6. Allow IAM user access to their own bucket with their IAM user id

Because the username is a human readable name, which is not require by AWS to be globally unique. So to avoid this issue, you may use the “${aws:userid}” instead of “${aws:username}”

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow only user id folder",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket/${aws:userid}/*"
}
]
}

7. All IAM user access to selected folder

This policy allow the user access to only Development folder and the content in the folder. We use the condition where to allow only Development folder inside the awsexamplebucket. Noted that “s3:prefix” is require for the folder-like access, if that’s no prefix parameter exists, than S3 will assume it’s a object keys.

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow only development folder",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket"
"Condition": {
"StringLike": {"s3:prefix":["Development/*"]}
}
}
]
}

8. Deny IAM user access to selected folder

We also can use the same condition to deny the access to certain folder under the bucket, if you wish to deny all access to private folder in any bucket, just replace the resources to “arn:aws:s3:::*”

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Deny access to private folder",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket"
"Condition": {
"StringLike": {"s3:prefix":["Private/"]}
}
}
]
}

9. Allow only bucket root level access

To allow the bucket root level access only, we can change the condition to “StringLike”: {“s3:prefix”:[“”]}

{
"Id": "ExamplePolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow root level access",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket"
"Condition": {
"StringLike": {"s3:prefix":[""]}
}
}
]
}

There are a lot of possibility that can be set in the s3 policy based on your company usage, the above is only some of the policy which I can think of and has been use in my working environment.

I will keep on update the list if there is any of the policy which I think is good to know and useful in real environment.

Originally published at https://tech.david-cheong.com on August 28, 2020.

--

--

No responses yet