I have setup a static website on AWS S3 and am accelerating it with AWS Cloudfront, but after, I am able to use AWS Route53 to connect my domain name to the Cloudfront endpoint. Now there are two other point of entries, S3 and Cloudfront (aside from the domain name).

Is it possible to hide the S3 and Cloudfront endpoints from the public so that they can only access website via the set domain name?

Thanks a lot!


Yes you can. For hiding S3 you use origin access identities and not expose s3 endpoint to any other service other than CloudFront.

To restrict access to CloudFront you have 2 choices. You can either use CloudFront's private content feature and restrict access by time or to specific IPs. Or, you can use AWS WAF and block access to any source IPs other than specific ones you want to allow

  • Ok great will try how to hide the s3 one allowing only cloudfront. Next is do you know how i can redirect non-www to www using cloudfront? I am hosting a website using cloudfront that gets assets from s3, and i want to redirect all non www to www. What is right way to do this? I have searched over the internet for past 3 hours and nothing works like i want it. – uberrebu Jul 24 '16 at 19:26
  • @babababa please don't raise new questions in comments. You may have overlooked this and this and this in your 3 hour search, but tl;dr you need an empty S3 bucket configured to redirect the requests, and a second CloudFront distribution to do this with HTTPS support on the alternate domain from which requests are redirected. – Michael - sqlbot Jul 24 '16 at 20:31
  • 1
    @user366914 this answer overlooks one potentially important point -- if you're using any S3 static web site hosting features behind CloudFront, like index and error documents or rewrite rules, you must then be using the web site endpoint for the bucket as the CloudFront origin, and that probably won't work with an origin access identity; this should only work against the bucket's REST endpoint. – Michael - sqlbot Jul 24 '16 at 20:48

Is it possible to hide the S3 endpoints from the public so that they can only access website via the set domain name?

Well, as far as I'm aware, there is no official solution so far, however there is a workaround suggested by AWS. So here is an implementation that worked out for me:

  1. Create an S3 bucket and enabled website hosting. Go to Bucket Policy section of Permissions and enter a policy similar to this one:

        "Version": "2012-10-17",
        "Statement": [
                "Sid": "PublicReadForGetBucketObjects",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::[YOUR_WEBSITE_BUCKET_NAME]/*",
                "Condition": {
                    "StringEquals": {
                        "aws:Referer": "[SOME_LONG_SECRET_VALUE]"
  2. Create CloudFront distribution and configure:

    1. the following origin: [YOUR_WEBSITE_BUCKET_NAME].s3-website-[AWS_REGION_NAME].amazonaws.com. Addressing this concern, from CloudFront perspective, this is not an S3 Bucket Origin, but rather just a Custom Origin.
    2. the following Origin Custom Header:
      • Header Name: Referer
      • Value: [SOME_LONG_SECRET_VALUE] (from your bucket policy)
  3. Configure the rest of your CloudFront distribution settings as usual.

As a result, bucket policy will allow object GETs if only the request contains Referer header with specified secret value, which will block direct request to you S3 website and allow requests sent via CloudFront. And, obviously, you might think of rotating this secret value every now and then.

Please note that by doing this, CloudFront will overwrite Referer header (if present) of any incoming request before forwarding it to the origin, so if you rely on it, this solution won't work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.