AWS S3: Bucket Policies By IP

Cloud infrastructure visualized

Introduction

Recently, I had a client that was only wanting his employees to be able to access their AWS S3 buckets from their internal network. My first though on this was setting up bucket policies based on their public IP. This would allow the employees to access the contents of the S3 bucket while having public access on, without giving access to all of the public.

Setting The Bucket Policy

This article assumes that you already have an AWS S3 bucket set up. If you need a nice guide on how to set up your S3 bucket, check out my article here. Go into your bucket and select the permissions tab. Chances are, your permissions look very similar to the ones below if it was setup with the defaults.

Default configuration for the Bucket Policy. Shows that the public access is turned off and there is no JSON in the bucket policy.

The default recommendations are to block all public access to the S3 bucket. Sometimes this isn’t ideal and you need to have public access to the bucket contents but don’t want all of the public to see your impertinent information.

This is where the Bucket Policy comes in. A bucket policy is where you can specify permissions for each resource to allow or deny actions requested. This provides granular access to the bucket using JSON configuration. If you don’t know JSON or don’t want to remember all of the different actions that you can do with the policy, AWS has a handy tool called the AWS Policy Generator. With this tool you can select all of the allow/deny actions you want and the JSON will be generated for you.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket-name-here/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "x.x.x.x/32"
                }
            }
        }
    ]
}

Going Over The JSON

This JSON is pretty simple to read through, just read it like you would a book. “Statement” is the main object and is like the chapter title. Everything that is indented inside of the “Statement” object are the words that tell the story within that chapter. Lets break this down further…

"Effect": "Allow", : The only options for this is Allow or Deny and is pretty self-explanatory

"Principal": "*", : The principal statement is less self-explanatory. This is the users that have access to this policy. You will put the IAM arn address for each user you want to be a part of this policy separated by a comma. The asterisk is the universal way to say all. So with this line, all IAM users are affected by this policy.

“Action”: “s3:GetObject” : This is the action requested. There are loads of actions that can be here. The Policy Generator has the full list of actions to choose from to best fit your need.

“Resource”: “arn:aws:s3:::bucket-name-here/*” : This specifies the resource within the bucket. Again, the asterisk means all resources can be accessed.

"Condition": {
                "IpAddress": {
                    "aws:SourceIp": "x.x.x.x/32"
                }

This is the main condition for the bucket policy. This says that only users with a source IP designated can access the contents. By setting this to the WAN IP, you can limit access to only your office/home.

Problems

Like everything in life, there are issues. What if you have an employee that is working from home and need to access the business critical information in that S3 bucket. Well they can’t because of this bucket policy. If this becomes an issue you would need to set up a VPN to the corporate network for the work form home users to access these resources.

Conclusion

Setting up a bucket policy is a great way to limit the public scope that it reaches. There are loads more things that you can do with bucket policies because of the granularity in permissions that it provides.

If you want to learn more about bucket policies or S3, please leave a comment and let me know!