Implementing SSL on Amazon S3 Static Websites

Since this post was written, Amazon has launched AWS Certificate Manager, which provides certificates at no cost and substantially simplifies managing them for use in the AWS context. We recommend that readers investigate the AWS Certificate Manager product before following the guidance in this post.

Every day, more and more websites are serving their pages using HTTPS. This can lead to warnings or complete failures when those sites want to embed content from other sites. Until recently, that included embedding work created with Knight Lab's TimelineJS and StoryMapJS. We recently implemented HTTPS to solve this problem, but it was less straightforward than we would have liked. Hopefully this guide will help others who are trying to do the same.


Many of Knight Lab's sites, including the CDN which serves our publishing tools, are served as static websites using Amazon's S3 service. Amazon S3 has always supported SSL using the domain name (e.g., However, using that means that if we ever wanted to switch away from Amazon for the service, pages using those URLs would break.

It would be better to use a custom domain name — to serve pages from — so that we could move that service if we ever want to. Until recently, setting this up involved a $600/month fee for a dedicated IP address. Last year, Amazon added the ability to use your own SSL certificates with Amazon CloudFront at no additional charge with Server Name Indication (SNI). While Amazon's guides to SSL for S3 mention that SNI is not universally supported in browsers, it is so widely supported that we saw no reason for concern.

Making it happen

There are five basic steps. Some of them get a little involved.

  1. Obtain an SSL certificate
  2. Upload your SSL certificate
  3. Configure your S3 bucket
  4. Create a CloudFront "Web" distribution
  5. Point your domain name to the CloudFront domain name.

Obtain an SSL certificate

Some of these details will vary based on the certificate authority you choose for your SSL certificate. Generally, the cost for certificates varies based on the strength of encryption and the lengths to which the authority goes to verify details about the organization making the request. Since we don't conduct e-commerce or handle highly sensitive data, we chose a relatively inexpensive option: we purchased a PostiveSSL Wildcard SSL certificate from Namecheap. ("Wildcard" means we can use a single certificate to secure multiple subdomain names.)

No matter which authority you choose, you must generate a Certificate Signing Request (CSR). This request is a formal way of indicating that your organization controls the domain name for the site where the certificate will be installed. We followed these directions for generating a new private key and a CSR using OpenSSL. You would want to replace domain_com with something that is relevant to you and helps you manage these files.

openssl req -nodes -newkey rsa:2048 -keyout domain_com.key -out domain_com.csr

Once you have a CSR, you must submit it to the authority to have it signed. For Namecheap, go through the purchasing process, and then go to your SSL Certificates list page. Click the "Activate Now" link next to your certificate. Select "Apache + OpenSSL" and paste the contents of the CSR file you generated. You will receive an email with a link to approve the certificate.

After approval, you will get another email with a zip attachment containing your four certificate files. The name of the last file will be different based on the name of the file you uploaded in the previous step.

  • AddTrustExternalCARoot.crt (Root CA Certificate)
  • COMODORSAAddTrustCA.crt (Intermediate CA Certificate)
  • COMODORSADomainValidationSecureServerCA.crt (Intermediate CA Certificate)
  • STAR_domain_com.crt (PositiveSSL Wildcard Certificate)

These four SSL certificates, from the root certificate to the end-user certificate, represent the SSL certificate chain. You must bundle the intermediate and root certificates and install them along with your end-user certificate.

Create the bundle by combining the root and intermediate .crt files into a single file. The order of concatenation is important:

cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt >

Upload your SSL certificate to AWS IAM

To use your SSL certificate with CloudFront, you need to upload it to AWS IAM, which must be done using the AWS Command Line Interface tools. I already had Python 2.7 and pip installed, so I installed the tools using pip:

sudo pip install awscli

and configured the tools using the configure command:

aws configure

Then, upload your certificate:

aws iam upload-server-certificate \
--server-certificate-name \
--certificate-body file://STAR_domain_com.crt \
--private-key file://domain_com.key \
--certificate-chain file:// \
--path /cloudfront/

For more information about each parameter, run:

aws iam upload-server-certificate help

Configure your bucket

You need to set a policy on your S3 bucket so that CloudFront can read the content. In the S3 Management Console, select the bucket and open the Properties tab.

Amazon AWS console for configuring bucket properties.

Under Permissions, click "Add bucket policy". Enter the following policy (changing "your-bucket-name" to the name of your bucket) and save it.

"Principal": {
"AWS": "*"

While you're here, make a note of the "Endpoint" listed under the "Static Website Hosting" section. You will need this to set the origin for your CloudFront distribution.

Create a CloudFront "Web" distribution

Before creating your CloudFront distribution, you need to decide how long you want your objects to stay in the CloudFront cache before CloudFront forwards a request to your origin. You have many options.

Since we update our origins fairly often and want those changes to become effective within a short period of time, we decided to control caching using Cache-Control headers on our S3 objects.

  • Origin Domain Name = the bucket endpoint listed under "Static Web Hosting" in S3.
  • Origin Protocol Policy = HTTP Only. This specifies how CloudFront will contact your S3 website, and S3 website hosting only supports serving content over HTTP.
  • Viewer Protocol Policy = HTTP and HTTPS - we didn't want existing HTTP links to break
  • Forward Headers = Since we need CORS support, we whitelisted the "Origin" header.
  • Object Caching = Use Origin Cache Headers. This is where the decision on your cache policy comes into play.
  • Alternate Domain Names (CNAMEs) = Enter the domain name(s) that people will actually use to visit your website (e.g.
  • SSL Certificate = Chose "Custom SSL Certificate", and then select the certificate that you uploaded to IAM.
  • Custom SSL Client Support = Only Clients that Support Server Name Indication (SNI)
  • Default Root Object = index.html

Create the distribution and wait until the Status column shows it is deployed. It took up to 30 minutes for each of our distributions to be created.

Point your domain name to the CloudFront domain name

After it is deployed, the distribution info will list a domain name (e.g. You will need to point your human-friendly domain name to this domain name (e.g. create a CNAME record in Route53 for

Latest Posts

  • Building a Community for VR and AR Storytelling

    In 2016 we founded the Device Lab to provide a hub for the exploration of AR/VR storytelling on campus. In addition to providing access to these technologies for Medill and the wider Northwestern community, we’ve also pursued a wide variety of research and experimental content development projects. We’ve built WebVR timelines of feminist history and looked into the inner workings of ambisonic audio. We’ve built virtual coral reefs and prototyped an AR experience setting interviews...

    Continue Reading

  • A Brief Introduction to NewsgamesCan video games be used to tell the news?

    When the Financial Times released The Uber Game in 2017, the game immediately gained widespread popularity with more than 360,000 visits, rising up the ranks as the paper’s most popular interactive piece of the year. David Blood, the game’s lead developer, said that the average time spent on the page was about 20 minutes, which was substantially longer than what most Financial Times interactives tend to receive, according to Blood. The Uber Game was so successful that the Financial...

    Continue Reading

  • With the 25th CAR Conference upon us, let’s recall the first oneWhen the Web was young, data journalism pioneers gathered in Raleigh

    For a few days in October 1993, if you were interested in journalism and technology, Raleigh, North Carolina was the place you had to be. The first Computer-Assisted Reporting Conference offered by Investigative Reporters & Editors brought more than 400 journalists to Raleigh for 3½ days of panels, demos and hands-on lessons in how to use computers to find stories in data. That seminal event will be commemorated this week at the 25th CAR Conference, which...

    Continue Reading

  • Prototyping Augmented Reality

    Something that really frustrates me is that, while I’m excited about the potential AR has for storytelling, I don’t feel like I have really great AR experiences that I can point people to. We know that AR is great for taking a selfie with a Pikachu and it’s pretty good at measuring spaces (as long as your room is really well lit and your phone is fully charged) but beyond that, we’re really still figuring...

    Continue Reading

  • Capturing the Soundfield: Recording Ambisonics for VR

    When building experiences in virtual reality we’re confronted with the challenge of mimicking how sounds hit us in the real world from all directions. One useful tool for us to attempt this mimicry is called a soundfield microphone. We tested one of these microphones to explore how audio plays into building immersive experiences for virtual reality. Approaching ambisonics with the soundfield microphone has become popular in development for VR particularly for 360 videos. With it,...

    Continue Reading

  • Audience Engagement and Onboarding with Hearken Auditing the News Resurrecting History for VR Civic Engagement with City Bureau Automated Fact Checking Conversational Interface for News Creative Co-Author Crowdsourcing for Journalism Environmental Reporting with Sensors Augmented Reality Visualizations Exploring Data Visualization in VR Fact Flow Storytelling with GIFs Historical Census Data Information Spaces in AR/VR Contrasting Forms Of Interactive 3D Storytelling Interactive Audio Juxtapose Legislator Tracker Storytelling with Augmented Reality Music Magazine Navigating Virtual Reality Open Data Reporter Oscillations Personalize My Story Photo Bingo Photojournalism in 3D for VR and Beyond Podcast Discoverability Privacy Mirror Projection Mapping ProPublica Illinois Rethinking Election Coverage SensorGrid API and Dashboard Sidebar Smarter News Exploring Software Defined Radio Story for You Storyline: Charts that tell stories. Storytelling Layers on 360 Video Talking to Data Visual Recipes Watch Me Work Writing and Designing for Chatbots
  • Prototyping Spatial Audio for Movement Art

    One of Oscillations’ technical goals for this quarter’s Knight Lab Studio class was an exploration of spatial audio. Spatial audio is sound that exists in three dimensions. It is a perfect complement to 360 video, because sound sources can be localized to certain parts of the video. Oscillations is especially interested in using spatial audio to enhance the neuroscientific principles of audiovisual synchrony that they aim to emphasize in their productions. Existing work in spatial......

    Continue Reading

Storytelling Tools

We build easy-to-use tools that can help you tell better stories.

View More