Briefly, What is CORS?

Cross-Origin Resource Sharing (CORS) is a mechanism through which a web application (in this example, that’s the S3 bucket) uses special HTTP headers to inform a browser if a user has permission to access content from another web application.

If this is a new concept to you dear reader, please head over to MDN where you can find an excellent article on the subject.

S3, CloudFront and CORS

The reason I decided to write this post, is because it took me quite a bit of reading through the AWS documentation as well as a decent amount of trial and error to get the settings right.

So, dear future me (and anyone else facing this predicament), here is the recipe:

Step 1: Configure S3

First we need to configure the S3 to allow CORS when accessing content stored on the bucket. That is, when we are accessing files directly, without a CDN.

Head over to the S3 Management console and switch to the Permissions tab of the bucket. Then select the CORS configuration section.

AWS S3 Permissions

The CORS configuration editor gives us the ability to compose the CORS configuration for the entire bucket. For the sake of simplicity, we are going to define a single rule allowing access from any origin. (Of course, you will consider creating a separate rule for each origin your application will use before going in production).

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
</CORSRule>
</CORSConfiguration>

The syntax for a CORS Configuration can be found in the AWS documentation.

Step 2: Configure CloudFront

Finally, we need to configure CloudFront so that it will correctly cache the headers being passed between our client web application and S3. This is the tricky part which took me quite some time to figure out.

Open the properties of the CloudFront Distribution which needs to be configured and switch to the Behaviors tab.

Screenshot showing the list of Behaviors created by default for a new CloudFront Distribution

Next, click Edit and ensure the following are enabled:

allowed HTTP Methods setting showing the OPTIONS method is included

cached HTTP Methods setting showing the OPTIONS method will be cached

Screenshot showing the whitelisted headers for caching

The choice of headers here is not arbitrary. Actually, AWS has a document on the topic explaining the possible options.

CloudFront may need several minutes to propagate the new settings.