AWS CloudFront + S3 + Allow all CORS

If you’ve ever set up CloudFront with CORS you know that it can be a little tricky to get right. In fact, the configuration AWS recommends makes it incredibly difficult to take full advantage of the CloudFront caching while still honoring CORS.

If you have some specific set of allowed origins with different CORS rules, then forwarding the Origin header makes sense, but what about the case where you simply want to allow CORS for all origins? If you forward the Origin header it reduces the abilit to cache the response. If you want to support Simple Requests to skip the OPTIONS request AWS may not even return the proper CORS headers at all. I’ve even seen cases where if a GET request was made to a URL (like an image) without CORS then CloudFront would cache the non-CORS version of that resource, even if later requests added the Origin header. Of course this probably means I didn’t set up my CloudFront caching “exactly just right”, but why make things complicated?

Here’s one weird trick to set up CloudFront to allow all origins and cache aggressively, even on simple requests. Explicitly set the Origin custom header in the CloudFront distribution.


That’s it. Now every response will always have the CORS headers because when CloudFront forwards the request to S3 it includes the Origin header. Even on simple requests. You can probably put in any origin domain you want, but is just what I used.

GitHub Pages Custom Domain with SSL/TLS

The Overview

Route53 -> CloudFront ->

You’ll get the joys of having SSL/TLS on a custom domain backed by the ease of deployment and reliability of GitHub Pages.

The Price

  • Route 53 ($0.50)
  • CloudFront (pennies!)
  • SSL/TLS Cert (free!)

The Details

Get the certificate for your domain at Be sure your contact details on the domain are up to date because Amazon uses whois info to find out where to send the confirmation email. I like to request a certificate for the wildcard as well as the base domain, i.e. * and, that way I can use the same certificate if I want to have other CloudFront distributions for subdomains.

Screenshot from 2016-02-09 15:45:08

You’ll need to click through the links Amazon emails you so that they can validate your ownership of the domain and activate the certificate.

Next, create your CloudFront distribution. Choose “Web”. Configure your origin, in my case Choose “HTTPS Only” for Origin protocol policy, that way CloudFront will only connect to you GitHub pages over HTTPS.

Screenshot from 2016-02-09 15:55:14

Configure the caching behavior. Here I add OPTIONS to the allowed requests, I’m not sure if this is necessary since GitHub pages enables CORS by adding the Access-Control-Allow-Origin: * header to all responses. You also may want to customize and set the default TTL to zero. GitHub sets a 10 minute caching header on all resources found, but won’t set a header on 404s. This will prevent CloudFront from caching a 404 response for 24 hours (yikes!)

Screenshot from 2016-02-09 16:03:20

Here’s where we add our certificate. Be sure to set up the CNAME field with your domain, and be sure your certificate matches!

You’ll also want to set the Default Root Object to index.html.

Screenshot from 2016-02-09 16:13:28

You can also add logging if you’re feeling into it.

If your domain is hosted somewhere else you can transfer your DNS to Route53, otherwise you can set up the DNS records on your domain provider.

Create a Route53 Record set for your domain then create an A record. Choose Alias, and select the CloudFront Distribution as your Alias target. Note: you may need to wait ~10-15 minutes for the distribution to juice up.

Screenshot from 2016-02-09 16:17:53


You need to be careful with your urls (you’re careful with them anyway, right?!). You must include the trailing slash like, because if you don’t and do GitHub will respond with a 301 Redirect to your domain, and it won’t even keep the https!

If you hit a 404 CloudFront may cache the response for up to 24 hours with its default settings. This is because GitHub doesn’t set and caching headers on 404 responses and CloudFront does its default thing.