πŸ”“ Locking down your S3 buckets, for real

πŸ”“ Locking down your S3 buckets, for real

A practical guide πŸš€.

Β·

3 min read

πŸ’‘ 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:

  1. 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: Screen Shot 2022-02-13 at 1.18.50 PM.png

    • 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.
  2. 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 and s3: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?
Β