How can I restrict access to my Amazon S3 bucket using specific VPC endpoints or IP addresses?

Last updated: 2021-12-03

I want to block any traffic that isn't coming from a specific Amazon Virtual Private Cloud (VPC) endpoint or certain IP addresses. Or, I'm using an Amazon Simple Storage Service (Amazon S3) bucket to host a static website. The website must be accessible from specific VPC endpoints or IP addresses. How can I do that?

Resolution

Warning: The example bucket policies in this article explicitly deny access to any requests outside the allowed VPC endpoints or IP addresses. Be sure that review the bucket policy carefully before you save it.

Use a bucket policy to specify which VPC endpoints, VPC source IP addresses, or external IP addresses can access the S3 bucket.

Note: A VPC source IP address is a private IP address from within a VPC. Private addresses aren't reachable over the internet and can be used for communication between the instances in your VPC. For example, a private IP address can be an Amazon Elastic Compute Cloud (Amazon EC2) instance’s private IP address. For more information, see Private IPv4 addresses.

An external IP address is a public IP address that can be from within a VPC or outside of a VPC. For example, an external IP address can be an Amazon Elastic Compute Cloud (Amazon EC2) instance's Elastic or public IP address. Or, the external IP address can be the IP address of a VPC's NAT gateway or proxy server.

The following example bucket policy blocks traffic to the bucket unless the request is from specified VPC endpoints ( aws:sourceVpce):

{
  "Id": "VPCe",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VPCe",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": [
            "vpce-1111111",
            "vpce-2222222"
          ]
        }
      },
      "Principal": "*"
    }
  ]
}

Note:

The following example bucket policy blocks traffic to the bucket unless the request is from specified private IP addresses ( aws:VpcSourceIp):

{
  "Id": "VpcSourceIp",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VpcSourceIp",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Condition": {
        "NotIpAddress": {
          "aws:VpcSourceIp": [
            "10.1.1.1/32",
            "172.1.1.1/32"
          ]
        }
      },
      "Principal": "*"
    }
  ]
}

Note: To use this policy with the aws:VpcSourceIP condition, you must attach a VPC endpoint for Amazon S3. The VPC endpoint must be attached to the route table of the EC2 instance's subnet, and be in the same AWS Region as the bucket.

The following example bucket policy blocks traffic to the bucket unless the request is from specified external IP addresses ( aws:SourceIp):

{
  "Id": "SourceIP",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SourceIP",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Condition": {
        "NotIpAddress": {
          "aws:SourceIp": [
            "11.11.11.11/32",
            "22.22.22.22/32"
          ]
        }
      },
      "Principal": "*"
    }
  ]
}

Warning: These example bucket policies explicitly deny access to any requests outside the allowed VPC endpoints or IP addresses. Even the user that entered the bucket policy can be denied access to the bucket if the user doesn't meet the conditions. Therefore, make sure to review the bucket policy carefully before saving it. If you get accidentally locked out, see I accidentally denied everyone access to my Amazon S3 bucket. How do I regain access?

If you must allow specific users (within the same AWS account) access to the bucket, then include the following statement within the Condition block:

  • AROAEXAMPLEID is the role ID of an IAM role that you want to allow
  • AIDAEXAMPLEID is the user ID of an IAM user that you want to allow
  • 111111111111 is the AWS account ID of the bucket, which represents the credentials of the AWS account root user

For example:

"Condition": {
            "StringNotLike": {
                "aws:userId": [
                    "AROAEXAMPLEID:*",
                    "AIDAEXAMPLEID",
                    "111111111111"
                ]
            }
        }

For more information on granting access to specific IAM roles, see How to restrict Amazon S3 bucket access to a specific IAM role.


Did this article help?


Do you need billing or technical support?