It’s pretty common to make certain items in your S3 bucket are public to the internet, so that anyone can access and download them. However, there a few ways to go about this, which come with their own security concerns.
Should You Make an S3 Bucket Public?
The short answer is: probably not, and definitely not if you have any sensitive data. In most cases, it’s better to have something in front of the bucket, like an API server, that can respond to requests and handle authentication rather than just having all the objects public.
The exception is if you’re specifically serving web content from the bucket. S3 buckets can be configured to host static content, which is great for hosting large media like pictures and videos. You’ll, of course, need to make sure the bucket isn’t hosting content that’s supposed to be private, but the permissions can be set for each object, so it’s just something to keep in mind when uploading.
Another configuration is “public” access, but with an IP whitelist through the bucket policy to lock it down to only your servers. This doesn’t beat the security of just using IAM access keys, but it saves you from managing keys and makes the bucket function like it’s in your private subnet. If you’re running on EC2 though, you’ll want to just give the IAM role for the instance permission to access the buckets.
RELATED: How to Whitelist IP Addresses to Access an AWS S3 Bucket
The one thing you’ll never want to enable is public write access—this gives anyone in the world power to write to your bucket, delete items, or fill it up with large and expensive objects. There are very few use cases where you’d want to do this rather than having an API server in front to handle requests for you, but if you do want some form of public write, you should at least only enable s3:PutObject permissions, rather than full “write.”
Setting Up Public Access
There are a few different ways of managing public access on buckets. By default, S3 turns on all protections, making the entire bucket not public. You can selectively turn these off to enable varying levels of public data.
Under the “Permissions” tab in the buckets settings, you’ll find the controls for enabling public access. By default, all of these are checked. The first two deal with blocking public access granted to Access Control Lists attached to objects. If you leave these unchecked, you’ll be able to upload objects with public read permissions and have those be public. The last two block public access through the bucket policy, which just ensures that your policy can’t enable public access across the whole bucket without disabling this.
If you uncheck all of them, the bucket will display as “Objects Can Be Public.” Even with all these disabled, you’ll still need to enable public access with an ACL on the object itself, when you upload it. Usually this is done with the public-read ACL:
You can verify that this works by clicking on an object’s settings, and checking if “Read Object” under “Public Access” is set to true.
This is optional though, and is set at the object level. If you want to have public and private objects in one bucket, you can do that, though you may want to consider using separate buckets to ease any confusion.
Granting Bucket-Wide Access
To be clear here again—completely public S3 buckets are for hosting static web content, where every object in the bucket is intended to be exposed to the open internet. For anything else that needs some kind of public access, you should manage it at the object level with an Access Control List.
But, if you want to enable public access bucket-wide, you’ll need to do so with a bucket policy, like the following, that enables getObject permissions for everyone.
AWS will, of course, give you plenty of warnings that this bucket has blanket public access. This isn’t inherently a bad thing, but it is probably better to manage this at the object level unless this is specifically for hosting a website from.
Even despite this warning, many companies will make the mistake of storing sensitive data in public S3 buckets.