DEV Community

Danang Adi Nugroho
Danang Adi Nugroho

Posted on

S3 Security Best Practices: Require HTTPS and Restrict Access to a VPC Endpoint

Amazon S3 stores a lot of important data, so a weak configuration can expose it to the internet or to unwanted traffic. In this guide I walk through two practical ways I secure an S3 bucket: forcing HTTPS and limiting access to a specific VPC endpoint. It is written for beginners who already have an AWS account and want hands-on steps they can follow.

Prerequisites

Before you start, make sure you have:

  1. An AWS account with access to the AWS Management Console.
  2. A test S3 bucket you can safely experiment with, with at least one object uploaded.
  3. Permissions to edit S3 bucket policies and to create VPC endpoints (for example, administrator access or equivalent IAM permissions).
  4. The AWS CLI installed and configured, so you can run the verification commands.

Throughout this guide I use <YOUR_BUCKET_NAME> for the bucket name and <VPC_ENDPOINT_ID> for the VPC endpoint ID. Replace them with your own values.

Require HTTPS

Why it matters

By default an S3 bucket can accept both HTTP and HTTPS requests. HTTP traffic is not encrypted, so data can be read in transit. This bucket policy denies any request that does not use HTTPS, which protects your data while it moves.

Steps

  1. In the AWS Management Console, use the top search bar to search for and select S3.
    1. Click the bucket name.

S3 console showing the test bucket contents, with one object listed in the test/ folder
The S3 object view for the test bucket.

  1. Click the Permissions tab.
  2. Under Bucket policy, click Edit.
    1. Copy the bucket policy below and paste it into the bucket policy editor.
   {
       "Id": "S3-Security-Deny-unless-HTTPS",
       "Version": "2012-10-17",
       "Statement": [{
           "Action": "s3:*",
           "Effect": "Deny",
           "Principal": "*",
           "Resource": "arn:aws:s3:::<YOUR_BUCKET_NAME>/*",
           "Condition": {
               "Bool": {
                   "aws:SecureTransport": false
               }
           }
       }]
   }
Enter fullscreen mode Exit fullscreen mode

Replace <YOUR_BUCKET_NAME> with your bucket name.

Edit bucket policy screen in the S3 console showing the deny-unless-HTTPS JSON policy and the bucket ARN
The bucket policy editor with the HTTPS policy pasted in.

  1. Click Save changes.

How to verify it worked

  1. Test with an HTTP endpoint. This request should fail:
   aws s3api head-object --key [folder-name]/[filename] --endpoint-url http://s3.amazonaws.com --bucket <YOUR_BUCKET_NAME>
Enter fullscreen mode Exit fullscreen mode

The command should return a 403 error, because the endpoint URL uses HTTP.

  1. Now test with an HTTPS endpoint. This request should succeed:
   aws s3api head-object --key [folder-name]/[filename] --endpoint-url https://s3.amazonaws.com --bucket <YOUR_BUCKET_NAME>
Enter fullscreen mode Exit fullscreen mode

The command succeeds. Both commands use s3api, and the only difference is the --endpoint-url. So the bucket policy reacts to the transport, not to the tool.

Restrict Access to an S3 VPC Endpoint

Why it matters

A VPC endpoint lets resources inside your VPC reach S3 over the AWS private network instead of the public internet. This bucket policy denies every request that does not come through your VPC endpoint, so only traffic from your VPC can reach the bucket.

Steps

  1. In the AWS Management Console, use the top search bar to search for and select VPC.
    1. In the left column, click Endpoints.
    2. Click Create endpoint.
    3. Give the endpoint a name.

Create endpoint screen showing the Name tag field set to s3-endpoint and AWS services selected as the type
Naming the endpoint and choosing the AWS services type.

  1. Type S3 in the search bar and press Enter. This filters the list to the S3 endpoints. Select the Gateway type endpoint.

VPC service list filtered by s3, with the Gateway type com.amazonaws.us-east-1.s3 service selected
Selecting the S3 Gateway endpoint from the service list.

  1. Under VPC, select your VPC.

Network settings section showing a VPC selected in the VPC dropdown
Choosing the VPC for the endpoint.

  1. Configure the route tables and set the Policy to Full access.

Route tables selection and the Policy section set to Full access
Selecting the route tables and setting the endpoint policy to Full access.

  1. Click Create endpoint.
    1. In the AWS Management Console, use the top search bar to search for and select S3.
  2. Click the bucket name.
  3. Click the Permissions tab.
  4. Under Bucket policy, click Edit.
    1. Delete the existing bucket policy. Copy the bucket policy below and paste it into the bucket policy editor.
   {
       "Id": "S3-Security-Deny-unless-VPC-endpoint",
       "Version": "2012-10-17",
       "Statement": [{
           "Action": "s3:*",
           "Effect": "Deny",
           "Resource": "arn:aws:s3:::<YOUR_BUCKET_NAME>/*",
           "Condition": {
               "StringNotEquals": {
                   "aws:sourceVpce": "<VPC_ENDPOINT_ID>"
               }
           },
           "Principal": "*"
       }]
   }
Enter fullscreen mode Exit fullscreen mode

Replace <YOUR_BUCKET_NAME> with your bucket name and <VPC_ENDPOINT_ID> with your endpoint ID.

Edit bucket policy screen showing the deny-unless-VPC-endpoint JSON policy
The bucket policy editor with the VPC endpoint policy pasted in.

  1. Click Save changes.

How to verify it worked

  1. From an EC2 instance inside the VPC, run this command:
   aws s3api head-object --key [folder-name]/[filename] --bucket <YOUR_BUCKET_NAME>
Enter fullscreen mode Exit fullscreen mode

The request succeeds because the EC2 instance can route its S3 request through the VPC endpoint, and the bucket policy allows requests that come through that endpoint.

Clean Up

To avoid leftover resources and keep your account tidy, remove the test resources when you are done:

  1. In the S3 console, open the bucket, go to the Permissions tab, and under Bucket policy click Edit, then delete the policy and click Save changes.
  2. In the VPC console, open Endpoints, select the endpoint you created, and delete it.
  3. If you created a test bucket only for this guide, empty the bucket and then delete it.

Conclusion

Key takeaways:

  • Force HTTPS with a bucket policy that denies requests when aws:SecureTransport is false.
  • Restrict access to a VPC endpoint with a bucket policy that denies requests from any other source.
  • Verify each policy with the AWS CLI before you trust it.
  • Remove test resources when you finish.

Relevant official AWS documentation:

Top comments (0)