Security and identity
CloudFront signed URLs vs signed cookies: which one should you use?
By ImagineTechVerse5 min read
Exam prepSAA-C03
Some content should only reach the people who paid for it or signed in: a course video, a software download, a subscribers’ area. Amazon CloudFront can serve it privately in two ways, and they work the same way underneath:
- A signed URL carries the permission inside the link. One link, one file.
- Signed cookies carry the permission in the browser’s cookies. One set of cookies, many files, and your URLs don’t change.
How signing works
Both options follow the same steps:
- A user signs in to your application, which checks that they’re allowed to see the content.
- Your application signs a URL, or a set of cookies, with a private key that only it holds.
- CloudFront checks the signature with the matching public key, which you’ve uploaded to CloudFront and added to a trusted key group on the distribution.
- If the signature is valid and hasn’t expired, CloudFront serves the file. If it’s been tampered with or has expired, the request is rejected with a 403.
A few details worth knowing:
- Key groups are the recommended signer. The alternative, a CloudFront key pair, needs the AWS account root user to manage it. Key groups are managed through the CloudFront API, so you can automate rotation and control access with IAM.
- Keys must be RSA 2048 or ECDSA 256, in PEM format. By default a distribution can trust up to four key groups of up to five public keys each.
- Protection is set per cache behavior. You can require signing for
/members/*and leave the rest of the site public. - Lock the origin too. Signing only protects requests that go through CloudFront. If your files are in S3, use origin access control (OAC) so nobody can skip CloudFront and fetch them from the bucket directly.
Signed URLs: the permission in the link
A signed URL is your normal URL plus a few query string parameters. With the simplest kind of policy it looks like this:
https://d111111abcdef8.cloudfront.net/setup.exe
?Expires=1767290400
&Signature=nitfHRCrtziwO2Hw...
&Key-Pair-Id=K2JCJMDEHXQW5F
Expires is the end time as a Unix timestamp, Signature is the signed hash, and Key-Pair-Id is the
ID of the public key CloudFront should check it with.
Use signed URLs when:
- you’re protecting individual files, such as an installer download or a single report, or
- the client doesn’t support cookies, such as a custom HTTP client.
Signed cookies: the permission in the browser
With signed cookies, your application sends three Set-Cookie headers after the user signs in, and
the browser sends them with every request that follows:
Set-Cookie: CloudFront-Expires=1767290400
Set-Cookie: CloudFront-Signature=yXrSIgyQoeE4...
Set-Cookie: CloudFront-Key-Pair-Id=K2JCJMDEHXQW5F
The same three values as the signed URL, just carried differently. (With a custom policy,
CloudFront-Policy takes the place of CloudFront-Expires.)
Use signed cookies when:
- you’re protecting many files at once, such as every segment of a video in HLS format, or a whole subscribers’ area, or
- you don’t want to change your current URLs.
To make stolen cookies less useful, AWS suggests session cookies (no Expires or Max-Age attribute),
the Secure attribute, the narrowest Domain you can, a short expiry, and, where you can, a custom
policy that names the viewer’s IP address.
Canned or custom policy?
Whichever you choose, the signature covers a policy: the rules for when, and by whom, the content can be fetched. There are two kinds.
| Canned policy | Custom policy | |
|---|---|---|
| End time | Required | Required |
| Start time | No | Optional |
| Limit to an IP address or range | No | Optional |
| One policy for many files (wildcards) | No | Yes |
| Signed URL length | Shorter | Longer: the policy travels in the URL |
Rule of thumb: a canned policy for a simple “valid until” link; a custom policy when you need a start time, an IP limit or one signature across many files.
Side by side
| Signed URL | Signed cookies | |
|---|---|---|
| Grants access to | One file per URL | Many files with one set of cookies |
| Your URLs | Change: parameters are added | Stay the same |
| Needs cookie support | No | Yes |
| Typical use | A download link | A video stream, a members’ area |
| If both are present | Wins: CloudFront decides on the URL alone | Ignored |
Gotchas
- Don’t change a URL after signing it. The signature covers the URL as it was signed. If an email
tool appends
&utm_source=newsletterafterwards, CloudFront returns 403. Add every parameter before you sign, or use signed cookies and keep the URL clean. - Some parameter names are reserved. If your normal URLs already use
Expires,Policy,Signature,Key-Pair-IdorHash-Algorithm, you can’t use signed URLs or signed cookies: CloudFront treats those URLs as signed and won’t look at cookies. - Expiry is checked when each request arrives. A download that starts just before the expiry time can finish, but if it restarts after expiry, or a later Range request comes in, it fails.
- Cache behavior order matters. If a request matches a public behavior before the protected one, CloudFront serves it without checking any signature.
CloudFront signed URLs vs S3 presigned URLs
They sound alike, but they’re different features:
- A CloudFront signed URL is signed with a key in a CloudFront key group, is served through the CDN’s edge locations, and can carry a custom policy.
- An S3 presigned URL is signed with the AWS credentials of whoever created it, goes straight to S3, and gets that person’s permissions on one object.
If the content is served through CloudFront, use CloudFront signing, and keep the bucket private with OAC.
Exam traps
- “Paying users must download one specific file, for a limited time.” Signed URL.
- “Subscribers must access all the files in a members’ area without the URLs changing.” Signed cookies.
- “Protect a video stream made of hundreds of segment files.” Signed cookies.
- “The client application doesn’t support cookies.” Signed URL.
- “Access must start at a set time, or only from the office IP range.” A custom policy.
- “Users are bypassing CloudFront and downloading straight from the S3 bucket.” Origin access control (OAC), with the bucket policy allowing only CloudFront.
- “Avoid using the root user to manage signing keys.” A trusted key group.
For the full details, see the Amazon CloudFront Developer Guide on serving private content, choosing between signed URLs and signed cookies, signed URLs, signed cookies, trusted key groups and origin access control.
Drafted with AI assistance, then reviewed and edited by the ImagineTechVerse team and checked against the AWS documentation.
Test yourself
You’ve read it; now see how much stuck. These puzzles use the terms from this article.
More on Security and identity
Across & Down, the newsletter
New puzzles and one concept explained in plain English, straight to your inbox. Free, and you can unsubscribe anytime.
Subscribe free