This chapter covers CloudFront Signed URLs and Signed Cookies, two mechanisms to restrict access to private content distributed via Amazon CloudFront. These are essential for protecting premium content such as paywalled articles, software downloads, or streaming media. On the SAA-C03 exam, you can expect 2-3 questions related to CloudFront security features, including Signed URLs/Cookies, Origin Access Identity (OAI), and field-level encryption. Mastering Signed URLs and Cookies is critical for scenarios where you need to grant temporary access to specific users while preventing unauthorized sharing.
Jump to a section
Imagine a concert venue (CloudFront) that has a VIP section (private content). The venue has a security checkpoint at the entrance. For general admission (public content), anyone with a ticket can enter. But for the VIP section, the venue issues special passes that are cryptographically signed. Each pass contains: a unique ID, the name of the VIP, an expiration time, and a cryptographic signature created by a trusted authority (the venue manager). The security guard at the VIP entrance verifies the signature using a public key. If the signature is valid, the pass hasn't expired, and the VIP name matches, the guard allows entry. If any condition fails, entry is denied. The guard does not need to call the manager each time; the signature itself proves authenticity. This is exactly how CloudFront Signed URLs work: the URL contains policy information (like expiration and IP range) signed with a private key, and CloudFront verifies the signature using the corresponding public key. No server-side session state is needed; the URL itself carries the authorization.
What Are CloudFront Signed URLs and Signed Cookies?
CloudFront Signed URLs and Signed Cookies are mechanisms to control access to private content delivered through CloudFront. They allow you to restrict who can access your content, for how long, and optionally from which IP addresses. The key difference is that Signed URLs embed the access policy in the URL itself, while Signed Cookies store the policy in a cookie that the browser sends with every request.
Why Use Them?
Without these mechanisms, any CloudFront distribution configured to serve private content would require all viewers to be authenticated by an origin that validates requests. Signed URLs/Cookies offload this validation to CloudFront, reducing load on your origin and enabling edge caching. They are ideal for:
Premium content delivery (e.g., paywalled articles, video streaming)
Software downloads with time-limited access
Secure file sharing with specific IP restrictions
E-learning platforms where each student gets temporary access to course materials
How Signed URLs Work Internally
A Signed URL is a standard CloudFront URL with query string parameters that contain a policy and a signature. When a viewer requests a Signed URL, CloudFront:
Extracts the policy from the query parameters (either canned or custom).
Verifies the signature using the public key that corresponds to the private key used to sign the URL.
Checks that the current time is within the policy's time window.
Optionally checks the viewer's IP address against an IP range in the policy.
If all checks pass, CloudFront forwards the request to the origin (or serves from cache).
If any check fails, CloudFront returns HTTP 403 Forbidden.
Key Components
- Key Pair: You must create a CloudFront key pair (public/private) in the AWS account. The private key is used to sign URLs/Cookies; the public key is uploaded to CloudFront and used for verification. CloudFront key pairs are account-wide, not per distribution.
- Policy: A JSON document that specifies permissions. There are two types:
- Canned Policy: Allows only one URL, with a fixed expiration time. Cannot restrict IP or other conditions. Format: {"Statement":[{"Resource":"URL","Condition":{"DateLessThan":{"AWS:EpochTime":expiration}}}]}
- Custom Policy: Allows multiple URLs (using wildcards), can restrict IP ranges, set custom start/end times, and include other conditions like date greater than. Format: {"Statement":[{"Resource":"URL pattern","Condition":{"DateLessThan":{"AWS:EpochTime":expiration},"IpAddress":{"AWS:SourceIp":"IP range"}}}]}
- Signature: A base64-encoded, RSA-SHA1 signature of the policy (for canned) or the policy itself (for custom). The signature is computed using the private key.
- Expiration: Specified as an epoch timestamp. CloudFront checks the current time against this. For canned policies, expiration is required. For custom policies, you can also set a start time (DateGreaterThan).
- IP Restriction: Optional in custom policies. You can restrict access to a specific IP address or CIDR range. This is useful for corporate intranets.
How Signed Cookies Work Internally
Signed Cookies work similarly but the policy and signature are stored in cookies set on the viewer's browser. The viewer must first visit a sign-in endpoint that sets the cookies, then subsequent requests to CloudFront include the cookies automatically. CloudFront extracts the policy from the cookie, verifies the signature, and checks conditions.
CloudFront supports three cookies:
- CloudFront-Policy: Contains the base64-encoded policy (for custom policies).
- CloudFront-Signature: Contains the base64-encoded signature.
- CloudFront-Key-Pair-Id: Contains the ID of the CloudFront public key used to sign.
- For canned policies, you use CloudFront-Expires instead of CloudFront-Policy.
Step-by-Step Mechanism
Creating a Signed URL (Canned Policy):
1. Build the base URL: https://d123.cloudfront.net/private/file.pdf
2. Set expiration: e.g., 2025-12-31 23:59:59 UTC = 1767225599
3. Create policy JSON: {"Statement":[{"Resource":"https://d123.cloudfront.net/private/file.pdf","Condition":{"DateLessThan":{"AWS:EpochTime":1767225599}}}]}
4. Sign the policy with the private key (RSA-SHA1) to get signature.
5. Base64-encode the signature (URL-safe).
6. Append query parameters: ?Expires=1767225599&Signature=...&Key-Pair-Id=K123456
Creating a Signed URL (Custom Policy):
1. Build base URL pattern: https://d123.cloudfront.net/private/*
2. Set conditions: expiration, start time, IP range.
3. Create policy JSON.
4. Sign the policy (not the URL) to get signature.
5. Base64-encode policy and signature.
6. Append query parameters: ?Policy=...&Signature=...&Key-Pair-Id=K123456
Creating Signed Cookies: 1. Create policy (custom) or expiration (canned). 2. Sign to get signature. 3. Set cookies on the viewer's browser (e.g., via a backend application). 4. Cookies are automatically sent with subsequent requests.
Configuration and Verification
To configure CloudFront Signed URLs/Cookies:
1. Create a CloudFront key pair: In the AWS Management Console, go to CloudFront > Key Management > Create Key Pair. AWS generates a public/private key pair. Download the private key (.pem file) and store it securely. The public key is automatically stored in CloudFront.
2. Restrict viewer access: In your CloudFront distribution, create a behavior for the path pattern you want to protect (e.g., /private/*). Set "Restrict Viewer Access" to "Yes" and choose "Trusted Key Groups" or "Trusted Signers" (legacy). For SAA-C03, know that Trusted Key Groups is the modern approach; Trusted Signers (using AWS account IDs) is legacy.
3. Add the public key to a key group: Create a key group that contains the public key ID. Then associate that key group with the behavior.
4. Generate signed URLs/Cookies in your application using the private key.
Verification: Use curl to test a Signed URL. For example:
curl -v "https://d123.cloudfront.net/private/file.pdf?Expires=1767225599&Signature=abc123&Key-Pair-Id=K123456"If the signature is invalid or expired, you'll get a 403 response.
Interaction with Related Technologies
Origin Access Identity (OAI): OAI restricts access to the S3 origin so that only CloudFront can fetch objects. Signed URLs/Cookies control viewer access. They are often used together: OAI ensures the origin is not publicly accessible, while Signed URLs/Cookies grant temporary access to specific viewers.
AWS WAF: You can use WAF web ACLs to add additional security rules (e.g., rate limiting, IP blocking) on top of Signed URLs/Cookies.
Lambda@Edge: You can use Lambda@Edge to generate Signed URLs/Cookies dynamically at the edge, reducing load on your origin server.
AWS Secrets Manager: Store private keys securely and rotate them automatically.
Important Defaults and Limits
Signed URLs can be up to 2048 characters long (including query parameters). If your policy is large, consider using Signed Cookies to avoid URL length issues.
The signature algorithm is RSA-SHA1. CloudFront does not support newer algorithms like RSA-SHA256.
The expiration time is in epoch seconds. CloudFront uses the server time (UTC) for comparison.
You cannot use Signed URLs/Cookies with RTMP distributions (deprecated). For RTMP, use token authentication.
Signed Cookies are domain-specific: they work only for the CloudFront distribution domain (e.g., d123.cloudfront.net). If you use a custom domain (CNAME), you must set the cookie domain to the custom domain.
Common Exam Scenarios
Time-limited access: A company wants to grant 24-hour access to a downloadable file. Use a Signed URL with a canned policy and expiration set to 24 hours from now.
Multiple files: A user purchases access to all videos in a course. Use a Signed Cookie with a custom policy that includes a wildcard path (e.g., /videos/*) to allow access to all videos without signing each URL individually.
IP restriction: An enterprise wants to restrict access to internal users only. Use a custom policy with an IP range condition.
Geo-restriction: Use CloudFront geo-restriction (whitelist/blacklist) instead of Signed URLs for country-level access control. Signed URLs are for user-level control.
Create CloudFront Key Pair
In the AWS Management Console, navigate to CloudFront > Key Management > Create Key Pair. AWS generates an RSA key pair. The public key is stored in CloudFront with a unique ID (e.g., K123456). You must download the private key (.pem file) immediately; it cannot be retrieved later. The private key is used to sign URLs/Cookies in your application. For SAA-C03, remember that key pairs are account-wide; they are not specific to a distribution. You can have up to 5 key pairs per account.
Configure Distribution Behavior
In your CloudFront distribution, select the behavior (e.g., path pattern /private/*) and set 'Restrict Viewer Access' to 'Yes'. Then choose 'Trusted Key Groups' (modern) or 'Trusted Signers' (legacy). Create a key group that includes the public key ID from step 1. Associate that key group with the behavior. This tells CloudFront to reject any request that does not have a valid signed URL or cookie. Without this step, even with a signed URL, CloudFront will ignore it and serve content publicly.
Generate Signed URL in Application
Your backend application (e.g., running on EC2 or Lambda) uses the private key to generate a signed URL. For a canned policy, you construct the base URL, set expiration, create a policy JSON, sign it with RSA-SHA1, base64-encode the signature, and append query parameters. For a custom policy, you sign the policy itself. The resulting URL is given to the user (e.g., embedded in an email or web page). The signature is verified by CloudFront using the public key from the key group.
User Requests Content via Signed URL
The user clicks the signed URL. The browser sends an HTTP GET request to the CloudFront edge location. CloudFront receives the request and inspects the query parameters for Policy (or Expires), Signature, and Key-Pair-Id. It extracts the policy, decodes the signature, and uses the public key identified by Key-Pair-Id to verify the signature. If the signature is valid and the current time is within the policy's time window (and IP matches if specified), CloudFront forwards the request to the origin (or serves from cache). Otherwise, it returns 403 Forbidden.
CloudFront Serves Content
If the request passes validation, CloudFront retrieves the object from the origin (e.g., S3 bucket) or serves it from the edge cache. The object is then returned to the user. The user can now view/download the content. Subsequent requests for the same object within the cache TTL will be served from cache, but each request is still validated against the signed URL's conditions. Note that CloudFront caches the object, not the authorization; each request is independently verified.
Signed Cookie Alternative
Instead of generating a signed URL for every request, you can set a signed cookie on the user's browser. The user first visits an authentication endpoint (e.g., a login page) that validates their identity and then sets the CloudFront-Policy, CloudFront-Signature, and CloudFront-Key-Pair-Id cookies. Subsequent requests to CloudFront automatically include these cookies. CloudFront extracts the policy from the cookie and verifies it. This is more efficient for accessing multiple files, as you only need to set the cookie once per session.
Enterprise Scenario 1: Paywalled News Website
A large news organization uses CloudFront to deliver premium articles to subscribers. They have a legacy system where each article URL is dynamically generated with a signed URL that expires after 24 hours. The backend, running on EC2, uses a custom Lambda function to generate signed URLs upon user login. The private key is stored in AWS Secrets Manager. The distribution uses OAI to ensure only CloudFront can access the S3 bucket storing articles. The signed URLs include a custom policy with an IP range condition (the user's IP at login) to prevent sharing. However, they encountered a problem: mobile users on cellular networks have changing IPs, causing 403 errors. Solution: remove IP restriction for mobile users or use signed cookies with shorter expiration. Scale: They serve 10 million requests per day. Performance is not impacted because CloudFront caches the articles, and signature verification is computationally cheap. Misconfiguration: Initially, they forgot to restrict viewer access on the behavior, making articles publicly accessible despite signed URLs. They also used a canned policy, which limited them to one URL per signature, causing performance overhead from generating many signatures. They switched to custom policies with wildcards and signed cookies for premium content sections.
What SAA-C03 Tests
The SAA-C03 exam tests your ability to choose between Signed URLs and Signed Cookies based on the scenario. The objective code is Domain 2: Resilient Architectures, Objective 2.5: Determine how to implement and manage security and access controls for content delivery. You will see questions that describe a use case (e.g., a video streaming service with pay-per-view) and ask which method to use. Key decision factors: Signed URLs for individual files (e.g., a single download), Signed Cookies for multiple files (e.g., a whole course). Also, know that Signed URLs can be used with both canned and custom policies, but custom policies allow IP restriction and multiple resources.
Common Wrong Answers
Using Origin Access Identity (OAI) instead of Signed URLs: OAI restricts access to the origin, not the viewer. The exam will present a scenario where a user needs temporary access to a file; OAI alone won't help because it doesn't control viewer access.
Choosing CloudFront geo-restriction: Geo-restriction blocks entire countries, not individual users. If the scenario requires per-user access control, geo-restriction is wrong.
Confusing Signed URLs with presigned S3 URLs: Presigned S3 URLs grant access directly to an S3 object, bypassing CloudFront. If the scenario involves CloudFront, the answer is CloudFront Signed URLs, not S3 presigned URLs.
Selecting 'Trusted Signers' (legacy) over 'Trusted Key Groups': The exam prefers modern practices. Trusted Key Groups are recommended; Trusted Signers are legacy. If both are options, choose Trusted Key Groups.
Specific Numbers and Terms
Key pair limit: 5 per account.
URL length limit: 2048 characters (including query parameters).
Signature algorithm: RSA-SHA1.
Cookie names: CloudFront-Policy, CloudFront-Signature, CloudFront-Key-Pair-Id, CloudFront-Expires.
Epoch time: Used for expiration and start time.
Trusted Key Groups: The modern way to specify which public keys can sign URLs/Cookies.
Edge Cases and Exceptions
Custom origin with authentication: If your origin requires authentication (e.g., HTTP basic auth), Signed URLs/Cookies still work; CloudFront forwards the request to the origin after verification.
Multiple key groups: You can associate multiple key groups with a behavior, allowing different sets of signers (e.g., different departments).
Signed URLs with custom domain: If you use a CNAME (e.g., cdn.example.com), the signed URL must use the CNAME, not the CloudFront domain, because the policy's resource field must match the actual URL requested.
How to Eliminate Wrong Answers
If the question mentions 'temporary access' and 'single file', eliminate OAI, presigned S3 URLs, and geo-restriction.
If the question says 'user needs to access multiple files without re-authentication', signed cookies are better than signed URLs.
If the question mentions 'IP restriction', it requires a custom policy, so canned policy is not sufficient.
If the question involves 'streaming video', consider using signed cookies for the entire video library.
CloudFront Signed URLs and Signed Cookies control access to private content at the edge, offloading authentication from the origin.
Use Signed URLs for single-file access and Signed Cookies for multi-file access (e.g., a course with many videos).
CloudFront key pairs are account-wide; up to 5 per account. Use Trusted Key Groups (not Trusted Signers) for modern configurations.
Custom policies allow IP restriction, start/end times, and wildcard patterns; canned policies only allow expiration and a single resource.
Signed URLs have a 2048-character limit; if policy is large, use Signed Cookies.
Signed Cookies require cookies enabled; fall back to Signed URLs if cookies are disabled.
Always combine with Origin Access Identity (OAI) to lock down the S3 origin.
The signature algorithm is RSA-SHA1; private key must be stored securely (e.g., AWS Secrets Manager).
CloudFront validates each request independently; caching does not bypass authorization.
For geo-restriction, use CloudFront geo-restriction, not Signed URLs.
These come up on the exam all the time. Here's how to tell them apart.
Signed URLs
Embeds policy in the URL itself.
Ideal for single file access (e.g., one-time download).
Can be used with any client (no cookie support needed).
URL length limit of 2048 characters may be restrictive for large policies.
Requires generating a new URL for each file or session.
Signed Cookies
Stores policy in cookies sent with each request.
Ideal for multiple file access (e.g., entire website section).
Requires browser cookies to be enabled.
No URL length limit issues; policy is stored in cookies.
Only need to set cookies once per session; subsequent requests are automatically authorized.
Mistake
CloudFront Signed URLs and S3 presigned URLs are the same thing.
Correct
They are different. CloudFront Signed URLs grant access to content delivered via CloudFront and are verified by CloudFront using a CloudFront key pair. S3 presigned URLs grant direct access to S3 objects and are signed using AWS Signature V4 with IAM credentials. They are used for different purposes: CloudFront Signed URLs for CDN delivery with edge caching, S3 presigned URLs for direct S3 access without CloudFront.
Mistake
Signed Cookies require the user to accept cookies.
Correct
Yes, signed cookies require browser cookies to be enabled. If the user has cookies disabled, signed cookies will not work. In such cases, you must fall back to signed URLs. The exam may test this by asking what to do if a user reports access issues with signed cookies.
Mistake
You can use the same signed URL for multiple users.
Correct
Signed URLs are typically generated per user or per session. They can be shared if the policy allows (e.g., no IP restriction), but that defeats the purpose of access control. Best practice is to generate unique URLs for each user with appropriate expiration.
Mistake
CloudFront key pairs are per distribution.
Correct
CloudFront key pairs are account-wide. A single key pair can be used to sign URLs for any distribution in the same AWS account. However, you must associate the public key (via a key group) with the specific distribution behavior.
Mistake
Signed URLs work with any origin type.
Correct
Signed URLs work with any origin type (S3, EC2, HTTP server, etc.) as long as CloudFront is configured to restrict viewer access. The origin itself does not need to be aware of the signed URL; CloudFront handles verification.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
CloudFront Signed URLs are used to restrict access to content delivered through CloudFront. They are signed using a CloudFront key pair (public/private) and verified by CloudFront. S3 presigned URLs grant temporary access to S3 objects directly, signed using AWS Signature V4 with IAM credentials. Use CloudFront Signed URLs when you want CDN benefits (caching, edge locations). Use S3 presigned URLs for direct S3 access without CloudFront.
Yes. When generating a signed URL, the resource in the policy must match the actual URL the user will request. If you use a CNAME like `cdn.example.com`, the signed URL must use that CNAME, not the CloudFront domain (e.g., `d123.cloudfront.net`). The key pair and signature process is the same.
If the expiration time passes, CloudFront will return a 403 Forbidden on the next request (e.g., if the user refreshes the page or the video player requests the next chunk). For streaming, this can interrupt playback. To avoid this, set a generous expiration or implement token refresh logic using Lambda@Edge.
No. RTMP distributions (deprecated) do not support Signed Cookies. For RTMP, you must use token authentication or switch to a web distribution (which supports Signed Cookies). The exam may test this deprecated difference.
Create a new key pair in the AWS Management Console, update your application to use the new private key, update the key group to include the new public key, and then remove the old key from the key group. You can have up to 5 key pairs simultaneously, allowing rotation without downtime.
Trusted Signers is the legacy method that uses AWS account IDs (canonical user IDs) to specify which accounts can sign URLs/Cookies. Trusted Key Groups is the modern method that uses key groups containing public keys. Trusted Key Groups is recommended because it is more granular and easier to manage. The exam expects you to choose Trusted Key Groups.
Yes. CloudFront can be configured with an ALB as origin. You can still use Signed URLs/Cookies to restrict viewer access. The ALB itself does not need to validate the signed URL; CloudFront handles that. However, you may also need to secure the ALB using security groups or WAF to prevent direct access.
You've just covered CloudFront Signed URLs and Signed Cookies — now see how well it sticks with free SAA-C03 practice questions. Full explanations included, no account needed.
Done with this chapter?