# 🔓 Locking down your S3 buckets, for real

## 💡 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1644743937824/a-FozxjNl.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:
  ```terrafrom 
     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:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutAccountPublicAccessBlock",
                "s3:PutBucketPublicAccessBlock"
            ],
            "Resource": "*",
            "Effect": "Deny"
        }
    ]
}
```

* That's it 😄. Easy right?


