Setting up AWS to use S3 and CloudFront signed URLs

Who is this article for?

You want to upload files to AWS using S3, but you realize that, by default, files are accessible to everyone. In order to restrict access to your files, AWS provides a file access control mechanism through CloudFront. We'll explore how to combine both services and allow users with a special (signed) URL to upload and download the files identified by that special URL.

You will use CloudFront's Sign API to generate the signed URLs. Doing a PUT request to the signed URL, you will be able to upload your file to S3.

Setps

Let's get started with the steps to set this whole thing up.

S3 knows not much about access restriction. We'll delegate access control to CloudFront. First we'll set up CloudFront, creating an OAI, and then instruct S3 to block everything except for CloudFront which will manage S3 access.

Creating an S3 bucket

Enable the S3 service and create a bucket with some name, say meow-static

Access Management with CloudFront

Create a cloudfront distribution

Create a CloudFront distribution in charge of managing access to that S3 bucket.

Go to CloudFront Distributions and click Create Distribution.

While creating the CloudFront distribution you will be asked to choose a Signer to **Restrict viewer access **. By default, nothing is selected. If you enable it (Yes), you will be asked for a Trusted authorization type:

  • Trusted key groups (recommended)
  • Trusted signer

We'll use the first option, but we need to create a key group. A key group is a set of Private-Public keys, that are allowed to generate signed requests in this CloudFront ditribution to access the Origin (the S3 bucket). The process, is to create a public key, assign it to the key group, and assign that key group to our distribution as a Trusted key group.

Create a cloudfront public key

Let's generate a Private-Public key pair in our computer and add it as a public key in CloudFront.

cd ./my-project
openssl genrsa -out private_key.pem 2048
# extract the public key into public_key.pem
openssl rsa -pubout -in private_key.pem -out public_key.pem
# print out the public key and copy it
cat public_key.pem

Once you have copied the newly generated public key, create a new key in your cloudfront management console, by clicking Create public key. Give it a name that describes who owns this private key (e.g. my-s3-cf-signing-software-node1), and paste the Public Key you generated above, under Key.

Create a cloudfront key group

Go to your cloudfront console, click the create key group button. Again you are asked a name for this group. This time, you can give it a name that corresponds to a grouping of the keys it contains, or what this group will be allowed to sign (e.g. key-group-for-s3-cf-signing). You may be able to adapt names to fit discrimination requirements.

Assign the public key we created just before (it should appear in the Public keys menu at the bottom).

Assembling back the pieces

We now can go back to our CloudFront distribution we just created (if you closed the tab, go back to CloudFront Management Console, select your distribution, and under the Behaviors tab, select the existing one and click Edit, or create one), and assign the newly created key group.

  1. Create a CloudFront OAI (Origin Access Identity)

Restricting S3 to CloudFront only

Configure your S3 bucket permissions so that CloudFront can use the OAI to access the files in your bucket and serve them to your users. Make sure that users can’t use a direct URL to the S3 bucket to access a file there.