How to use CloudFront Trusted Key Groups parameter and the trusted_key_group Terraform resource

How to use CloudFront signed URLs without the root user

Author's image
Tamás Sallai
7 mins

Signed URLs in AWS

Recently, AWS added a powerful and well-needed function to CloudFront: Trusted Key Groups. They allow using CloudFront signed URLs without involving the account root user.

Signed URLs are a way to provide controlled access to private resources. The canonical example is giving access to ebooks or other digital goods: you want to only allow downloading them for users who bought them and not everybody. Since the users don't have AWS accounts you can't use the traditional access control mechanism of AWS to grant/deny access to the files. Instead, you keep the files private but implement a URL signing process on the backend: the code checks if the user bought the content then returns a special URL that allows temporary access to the file. It is compatible with serverless backends, in fact, it's the only way to send large files to the users in that case.

In AWS, both S3 and CloudFront implemented signed URLs. The former uses the IAM service to delegate permissions, reusing the Access Key ID/Secret Access Key mechanism that underlies all AWS API calls. This integrates well with other parts of AWS and tools. But CloudFront signed URLs use a separate way: they rely on public/private keys where the public part is added as a trusted key and the other one is used for the signing itself.

For the first 12 years, CloudFront only supported adding these keys to the account using the root user. This goes against all security best practices and made deploying solutions that relied on this signing a pain. I advocated that S3 signed URLs should be the preferred way to implement private content signing wherever possible.

But CloudFront signed URLs are superior to their S3 counterparts. You can use an S3 bucket behind CloudFront as well as any other type of backend, and its signed URL mechanism can protect all of them. On the other hand, S3 can only sign URLs for objects in S3.

That's why I see the support for Trusted Key Groups as a great feature of CloudFront: you can now use signed URLs without worrying about all those problems an account-level setting would entail.

Especially now that Terraform added support for the resource and the setting, it is ready for prime time.

So, let's see how to implement a proper CloudFront signed URLs solution!

Here's a screencast of how deploying and using a Terraform solution works:

May 4, 2021
In this article