As a fellow technologist, I‘m sure you know that like all cloud services, you‘ve got to take responsibility to secure cloud storage. In this article, I want to have a geeky chat about some of the best tips I‘ve learned over the years to secure AWS S3 storage.
Before we dive into the security tips, we should talk about why S3 security is so crucial nowadays. Back in 2017, major S3 breaches exposed critical data like private social media accounts and classified data from the Pentagon. Since those big breaches, every organization I‘ve worked with pays very close attention to locking down their data stored in AWS S3.
Does this mean S3 is inherently insecure? Nah, I don‘t think so – S3 is a secure cloud storage solution at its core. But security does depend on how users configure and manage their S3 environments.
Alright, let‘s geek out on some of my favorite S3 security best practices…
Shared Responsibility Means Shared Security
Most cloud services like S3 use a Shared Responsibility Model for security. AWS takes care of securing the underlying cloud platform, while we as customers are responsible for properly configuring security in our own cloud usage.
The diagram below outlines the basic security responsibilities between AWS and S3 customers:

It‘s important we understand the security owned by AWS versus the security we own ourselves. While AWS provides some great tools to help us stay secure which I‘ll cover later, we can‘t rely 100% on Amazon – we need to take proactive measures to lock down our own S3 environments.
Alright, let‘s jump in to some of my favorite ways to do that…
1. Bucket Organization: Private vs Public
When you first create an S3 bucket, the default is a private bucket with no public access. Any new objects uploaded are also private by default.
To grant access to other users or applications, we need to manually configure bucket policies, ACLs, or IAM policies.
While we can mix private and public objects within a single S3 bucket, I‘ve found that gets messy quick. We end up spending too much time fiddling with convoluted ACLs to carve out public vs private access.
My recommendation: use completely separate S3 buckets for public versus private data.
For public data, create a bucket with an open policy like:
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOURPUBLICBUCKET/*"
}
This grants anyone on the Internet access to objects in that bucket.
Then keep a totally separate bucket for private data, locked down by default. Use IAM policies to selectively grant access to users or apps that need it.
Keeping public and private segregated avoids accidentally exposing private data down the road.
2. Enable Encryption to Protect Data
Encryption is a must these days to protect data at rest and in transit.
AWS offers a few encryption options for S3:
-
Server-side encryption – S3 can automatically encrypt objects when storing them. Uses either S3-managed keys or KMS keys.
-
Client-side encryption – For full control, encrypt objects client-side before uploading to S3.
Either way, I highly recommend using encryption on all S3 buckets. It‘s an easy win for security.
To enforce encrypted data transfer, add this bucket policy denying HTTP requests:
{
"Action": "s3:*",
"Effect": "Deny",
"Principal": "*",
"Resource": "arn:aws:s3:::YOURBUCKETNAME/*",
"Condition": {
"Bool": { "aws:SecureTransport": false }
}
}
Now only HTTPS can be used to interact with the bucket.
3. Monitor S3 Activity with CloudTrail
CloudTrail provides visibility into activity across your AWS accounts. It records API calls made by users, applications or AWS services.
CloudTrail offers both management events (high-level resource changes) and data events (specific object-level actions) for S3.
Management events include bucket creation/deletion. Data events include object upload/download API calls.
Data events provide more granular tracing but aren‘t logged by default. Management events are on by default and cost nothing extra.
I suggest enabling an S3 data event trail to capture all S3 object activity. This will track things like who downloaded a particular file and when. Very handy for security monitoring and investigation.
CloudTrail logs events to S3 so make sure access is locked down.
4. CloudWatch Alarms Can Automate Monitoring
CloudTrail gives great visibility, but for automated monitoring and alerts, CloudWatch is essential.
With CloudWatch, we can set alarms that automatically trigger on suspicious API activity. For example:
- Object deletions spikes
- Sudden increase in failed console sign-in attempts
- New EC2 instances launched
We can even use CloudWatch Events to invoke Lambda functions in response to alarms and take automatic actions like:
- Block affected user‘s access
- Revoke compromised keys
- Disable breached resources
So CloudWatch takes monitoring to the next level. Instead of just logging, we can use events to trigger instant security responses. Much more robust than having to manually check audit logs.
Below are some key metrics I like to monitor for S3 security:
| Metric | Description |
|---|---|
| BucketPolicyChanges | Bucket policy updates indicating permissions changes |
| GetObject | Access attempts to download objects from a bucket |
| DeleteObject | Deletion events for objects in a bucket |
| PutObject | Uploads of new objects to a bucket |
Monitoring these metrics allows us to catch suspicious activity as it happens.
5. Lifecycle Policies to Limit Data Access
S3 lifecycle policies are an easy way to enhance security.
With lifecycle rules, we can:
- Transition objects to lower access tiers like S3 Infrequent Access or Glacier for archiving
- Permanently delete objects after a certain period of time
This removes access to outdated data and limits the blast radius if a breach did occur.
Say we have sensitive financial records. We could transition documents older than 1 year to Glacier. And automatically delete anything over 7 years old.
This keeps our S3 storage tidy while limiting access to stale data.
6. Lock Down Public Access
Accidental public exposure is still a top data breach culprit today.
Developers easily misconfigure S3 buckets and objects to be public facing unintentionally.
To prevent this, enabling S3 Block Public Access is a must. This adds a blanket deny to:
- Making buckets public via bucket policies
- Public ACLs on buckets or objects
- Any public access points
Block Public Access can be enabled in the S3 console:

Or via account-wide settings:

This gives us a safety net against accidentally opening up access.
7. Leverage AWS Trusted Advisor
AWS Trusted Advisor provides best practice checks across your AWS environment. One of its key features is security – it will flag S3 buckets inadvertently left public.
I suggest reviewing Trusted Advisor at least weekly. It‘s an easy way to catch misconfigurations early before they become data breaches.
Bonus: Third-Party Tools for Added Security
AWS provides robust native tools for S3 security as we‘ve discussed. But third parties offer some great additional capabilities:
Security Monkey – Scans infrastructure and alerts on policy changes leaving resources public facing. Great for S3 auditing and governance.
CloudMapper – Maps out cloud environments with visuals and security checks for things like public S3 buckets. Very handy for visualizing security posture.
Cloud Custodian – Automates security monitoring and response based on rules. Can lock down public access as soon as it‘s detected.
Whew, we‘ve covered a ton of ground here! If you made it this far, hope you have some new ideas to lock down your S3 environments. As always, hit me up on Twitter if you have any other geeky AWS security tips!