How do you serve premium content — like a paid video course or a private document — through CloudFront without making it publicly accessible? You use cryptographically signed credentials that CloudFront validates at the edge before serving any content.
Both mechanisms use a CloudFront Key Pair (a public/private RSA key pair). Your application server signs the credential with the private key. CloudFront validates it using the public key. No request reaches your Origin — validation happens entirely at the edge.
1. Signed URLs (The "Ticket")
A Signed URL embeds the authorization directly into the URL itself as query parameters.
https://d1234abcd.cloudfront.net/invoice-2024-01.pdf
?Expires=1735689600
&Signature=abc123xyz...
&Key-Pair-Id=APKAEIBAERJR2EXAMPLE
- Scope: Grants access to one specific file (the exact path in the URL).
- Expiry: You set an expiration timestamp. After that, the URL is invalid.
- Use cases: A one-time software download link, a specific invoice PDF, a time-limited preview of a single asset.
2. Signed Cookies (The "VIP Badge")
Instead of embedding credentials in the URL, your login server sets HTTP cookies on the user's browser. CloudFront reads these cookies on every subsequent request.
Set-Cookie: CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt...
Set-Cookie: CloudFront-Signature=abc123xyz...
Set-Cookie: CloudFront-Key-Pair-Id=APKAEIBAERJR2EXAMPLE
- Scope: Grants access to multiple files or an entire path pattern (e.g.,
/premium/*or/course/module-3/*). - Use cases: Video streaming (HLS/DASH breaks a video into thousands of small
.tssegment files — you cannot practically sign a URL for each one), members-only website sections, multi-file software packages.
Critical Constraint: Don't Mix S3 Pre-Signed URLs with CloudFront
This is a common and painful mistake. S3 Pre-Signed URLs are signed with your IAM credentials and are validated by S3 directly. CloudFront Signed URLs are signed with your CloudFront Key Pair and validated by CloudFront. They are completely different systems.
If you put CloudFront in front of an S3 bucket and use S3 Pre-Signed URLs, CloudFront will not recognize the S3 signature — it will either strip the query parameters (breaking the URL) or pass them through to S3 where they may work inconsistently. The correct pattern is:
- Make your S3 bucket private (no public access).
- Create an Origin Access Control (OAC) so CloudFront can access S3 privately.
- Use CloudFront Signed URLs or Signed Cookies for user-facing access control.
A common interview scenario: "We put CloudFront in front of S3 and used S3 Pre-Signed URLs for secure downloads, but users are getting 403 errors intermittently." The answer is the signing mismatch — CloudFront strips or mishandles S3 query string signatures. The fix is to switch to CloudFront Signed URLs with an OAC-protected S3 origin.