π‘ Introduction
One of the foundational security elements of S3 is to ensure S3 buckets are not publicly accessible. It's such an established best practice that AWS makes it pretty difficult for S3 buckets and their objects to become public.
βBut I want to host my angular app in a bucket
There are some legit use cases where data in a bucket needs to be public. But still, making a bucket public is not a safe option. There are more secure alternatives that I will talk about in another post.
Why do I need policies to enforce thisβ
Keeping tabs on the S3 permissions in a single account is manageable, but for large-scale organizations, it becomes impossible. Hence, having some cloud governance around the S3 buckets becomes a necessity.
Luckily, AWS provides the necessary tools to achieve this task. Combining these tools can prevent new public bucket access or even override the existing public buckets. The latter option can cause some issues with the live applications, so you need to be careful here.
Ok, enough with the intros, let's get technical.
π TLDR
To lock your S3 buckets across multiple accounts, make sure to define the Account block public access
setting, then enforce its immutability by defining an SCP to deny any changes on it.
π Assumptions
While writing this post, I've made the following assumptions around your AWS setup:
- All of your accounts are grouped under an organization account
- You currently have some S3 buckets that are serving public traffic that you don't want to disrupt
π Steps
To prevent public bucket access, you need to do the following:
First, you need to define the policy that governs public access on the account level ( Across all S3 buckets ). You can do this via the AWS console:
- You will need to apply this step across all your AWS accounts. Luckily there is a Terraform IaC that you can use; it should look like the following:
resource "aws_s3_account_public_access_block" "this" { block_public_acls = true block_public_policy = true ignore_public_acls = false restrict_public_buckets = false }
- Note: applying this policy will only impact the newly created buckets; It will not impact all previously exposed buckets.
- You will need to apply this step across all your AWS accounts. Luckily there is a Terraform IaC that you can use; it should look like the following:
Now that you've applied the policy across all accounts, you need to make sure that no one can change this setting. Since your accounts are part of an organization's account, you can enforce this by applying an SCP that denies access to the
s3:PutAccountPublicAccessBlock
ands3:PutBucketPublicAccessBlock
S3 actions. Your SCP should look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutAccountPublicAccessBlock",
"s3:PutBucketPublicAccessBlock"
],
"Resource": "*",
"Effect": "Deny"
}
]
}
- That's it π. Easy right?