How To Use CloudFront Signed URLs for Secure Content Distribution

--

Photo by Dan Nelson on Unsplash

In today’s digital landscape, content distribution is a critical aspect of web applications. Amazon CloudFront is a robust content delivery network (CDN) service that accelerates the delivery of your web content, including images, videos, and other assets. To enhance security and control access to your content, CloudFront offers signed URLs, allowing you to grant temporary access to specific resources.

Understanding CloudFront Signed URLs

CloudFront signed URLs are URLs that grant access to private content for a limited time. These URLs contain cryptographic signatures created using a pair of public and private keys. The private key is used to sign the URL, and the corresponding public key, uploaded to CloudFront, is used to verify the signature. This process ensures that only users with the appropriate signed URL can access the protected content during the specified time frame.

Prerequisites

Before diving into the implementation, make sure you have the following:

  1. AWS Account: Ensure you have an AWS account and access to CloudFront.
  2. AWS SDK for Ruby: Install the aws-sdk-cloudfront gem using:gem install aws-sdk-cloudfront
  3. Generate Key Pair: Use OpenSSL to generate a key pair. Run the following commands:
Generate private key openssl genrsa -out private_key.pem 2048
Generate public key openssl rsa -pubout -in private_key.pem -out public_key.pem

Upload Public Key to CloudFront:

  1. Log in to the AWS Management Console.
  2. Navigate to CloudFront. Go to the Key management tab select “Key Pairs.”
  3. Create a new key pair and paste the contents of public_key.pem into the "Public Key" field.
  4. Note down the “Key Pair ID” for later use.
Creating a Key and Uploading in Cloudfront

5.After uploading the key go the Key Groups tab under Key management and then create a key group. While Creating the Key group you can select the public key you uploaded.

Creating a Key Group

Creating a Signing URLs.

Now, let’s dive into Ruby code to generate a signed URL using the AWS SDK for CloudFront.

require 'aws-sdk-cloudfront'
# Set expiration time (in this case, 5 minutes from now)
expiration_time = 5.minutes.from_now
# Replace the placeholders with your CloudFront key pair ID and private key
key_pair_id = "KXXXXXXX"
private_key = File.read("private_key.pem")
# Create a signer instance
signer = Aws::CloudFront::UrlSigner.new(
key_pair_id: key_pair_id,
private_key: private_key
)
# Specify the CloudFront URL of the protected resource
cloudfront_url = "https://yourcdnurl.cloudfront.net/test.gif"
# Generate a signed URL
signed_url = signer.signed_url(cloudfront_url, expires: expiration_time)
puts "Signed URL: #{signed_url}"

Make sure to replace "https://yourcdnurl.cloudfront.net/test.gif" with the actual CloudFront URL of your protected resource.

Here is the same exact code using Javascript as well.

npm install aws-sdk aws-amplify


const AWS = require('aws-sdk');
const amplify = require('aws-amplify');

// Configure AWS Amplify with your AWS credentials
amplify.configure({
Auth: {
identityPoolId: 'your_identity_pool_id',
region: 'your_aws_region',
},
});

// Set expiration time (in seconds)
const expirationTime = Math.floor((Date.now() + 5 * 60 * 1000) / 1000); // 5 minutes from now

// Replace the placeholders with your CloudFront key pair ID and private key
const keyPairId = 'K2Y5YT6J9Q13223432LTM';
const privateKey = `-----BEGIN PRIVATE KEY-----
yourprivate key
-----END PRIVATE KEY-----`;

// Specify the CloudFront URL of the protected resource
const cloudfrontUrl = 'https://yourcdnurl.cloudfront.net/test.gif';

// Create a CloudFront signer instance
const signer = new AWS.CloudFront.Signer(keyPairId, privateKey);

// Generate a signed URL
const signedUrl = signer.getSignedUrl({
url: cloudfrontUrl,
expires: expirationTime,
});

console.log('Signed URL:', signedUrl);

Creating a CloudFront Distribution with Origin Access Control and Enforcing Access Restrictions

Step 1: Log in to AWS Management Console

  1. Open the AWS Management Console.
  2. Sign in with your AWS account credentials.

Step 2: Navigate to CloudFront

  1. In the AWS Management Console, navigate to the “Services” menu.
  2. Under the “Networking & Content Delivery” section, click on “CloudFront.”

Step 3: Create a CloudFront Distribution

  1. In the CloudFront dashboard, click on the “Create Distribution” button.
  2. Choose the delivery method:
  • Select “Web” for general web content.
  • Select “RTMP” for media streaming (not covered in this guide).

3. Configure the distribution settings:

  • Origin Settings:
  • Choose your origin type (e.g., S3 bucket).
  • Configure the origin settings based on your use case.
  • Default Cache Behavior Settings:
  • Set the “Viewer Protocol Policy” to “Redirect HTTP to HTTPS.”
  • Configure other settings based on your requirements.
  • Distribution Settings:
  • Set “Restrict Bucket Access” to “Yes.”
  • Choose an existing origin access identity (OAI) or create a new one.

Step 4: Configure Origin Access Control; (OAC)

  1. If you need to create a new OAC:
  • Under “Restrict Bucket Access,” click on the “Create Origin Access Identity” link.
  • Provide a name for the OAC.
  • Add the OAC to the S3 bucket policy to grant CloudFront access.

Step 5: Review and Create

  1. Review all your settings to ensure they match your requirements.
  2. Click on the “Create Distribution” button to create the CloudFront distribution.

Step 8: Enforce Access Restrictions with Signed URLs

  1. In the Behaviour go to Restrict viewer access
  2. Click Yes and then in Trusted authorization type choose the key group you genreated.
  1. Utilize the Ruby code provided earlier to generate signed URLs.
  2. Ensure the key pair ID in the Ruby code matches the one associated with the CloudFront distribution.
  3. Distribute the signed URLs to authorized users or embed them in your application.

By following these steps, you’ve successfully created a CloudFront distribution with Origin Access Control, enforced access restrictions, and generated signed URLs for secure content distribution. This approach ensures that only authorized users can access your private content through CloudFront.

Conclusion

CloudFront signed URLs provide a secure way to control access to your private content distributed through the CDN. By implementing signed URLs with Ruby and the AWS SDK for CloudFront, you can ensure that your valuable assets are only accessible to authorized users for a specified duration. This adds an extra layer of security to your content delivery strategy, safeguarding your digital assets from unauthorized access.

--

--

THE HOW TO BLOG |Siddhanth Dwivedi

Siddhanth Dwivedi | Senior Security Engineer & AWS Community Builder 👨🏾‍💻