CloudFront to EC2 Secure Paths with Signed Cookies and URLs

```html

CloudFront to EC2: Secure Paths with Signed Cookies and URLs

AWS CloudFront to EC2 secure architecture diagram

Amazon CloudFront is often used as a global content delivery layer in front of EC2 instances to improve performance, reduce latency, and add a security boundary between the public internet and your origin. When you need to restrict access to specific EC2-backed paths—for example, premium content, internal tools, or downloadable assets—CloudFront’s signed URLs and signed cookies give you a powerful way to control who can access what, and for how long.

Why Secure Paths Between CloudFront and EC2?

Without additional security, any user who discovers the CloudFront URL for a protected resource can fetch it directly, and anyone who has the origin (EC2) endpoint could bypass CloudFront altogether. This leads to several problems:

  • Unauthorized access to paid or private content
  • Uncontrolled sharing of links outside your application
  • Higher costs and origin load from unthrottled, unauthenticated requests
  • Security risk if your EC2 instance is directly exposed to the internet

Using signed URLs and signed cookies, you can require CloudFront to validate a cryptographic signature before serving the object, ensuring that only authorized clients can fetch content from your EC2 origin.

Core Concepts: Signed URLs vs. Signed Cookies

Signed URLs

A signed URL is a regular CloudFront URL with additional query string parameters that embed a signature and constraints such as expiry time and IP range. The browser or client gets a unique URL that is valid only for a specific time or user.

Best when:

  • You want to protect a small number of files per user
  • You can safely expose a per-asset URL that expires quickly
  • You are serving download links or individual video files

Signed Cookies

Signed cookies move the signature out of the URL and into HTTP cookies. Once the client receives the cookies (usually via login or authorization flow), it can access multiple paths or entire directories behind CloudFront without re-signing every single URL.

Best when:

  • You need to protect many files or a whole path at once
  • You want clean URLs without cryptic query parameters
  • You’re building a web app with sessions and user logins

High-Level Architecture

  1. User accesses your web app (for example, at https://app.example.com).
  2. The app authenticates the user (login, SSO, etc.).
  3. The app generates a signed URL or sets signed cookies for CloudFront.
  4. The user’s browser requests content from CloudFront at d123.cloudfront.net (or a custom domain like cdn.example.com).
  5. CloudFront validates the URL or cookies using your public key and policy.
  6. If valid, CloudFront fetches the object from the EC2 origin (if not cached), returns it to the user, and caches it according to your cache behavior.
  7. If invalid, CloudFront returns 403 Forbidden or a custom error response.

Step 1: Configure CloudFront with EC2 as an Origin

  1. Create or identify your EC2 application.
    • Expose the content to be cached on predictable paths, e.g. /premium/*, /downloads/*.
    • Use HTTPS (via an Application Load Balancer or directly on EC2) wherever possible.
  2. Create a CloudFront distribution.
    • Origin domain: set this to your ALB DNS or EC2 public DNS / IP (or internal private endpoint if using private networking).
    • Origin protocol policy: usually HTTPS only.
  3. Restrict direct access to the origin.
    • Use a security group or firewall rules to allow only CloudFront (and possibly administration IPs) to reach the EC2 / ALB.
    • Optionally, validate a custom header from CloudFront at the origin to ensure requests are truly coming from CloudFront.
  4. Define cache behaviors.
    • Default behavior: public or semi-public content.
    • Additional behavior for secure paths: e.g. path pattern /secure/*, with Trusted Key Groups configured (see later).

Step 2: Set Up CloudFront Key Groups and Keys

Signed URLs and cookies with CloudFront rely on asymmetric cryptography. You generate a key pair, keep the private key secret in your backend, and upload the public key to CloudFront via a Key Group.

  1. Create a key pair.
    • Generate an RSA key pair (for example with OpenSSL).
    • Store the private key securely (for example, AWS Secrets Manager or AWS KMS).
  2. Create a public key in CloudFront.
    • In the CloudFront console, go to Public keysCreate public key.
    • Paste your public key and give it a recognizable name.
  3. Create a key group.
    • Go to Key groupsCreate key group.
    • Add your public key to this group.
  4. Attach the key group to the secure cache behavior.
    • Edit the cache behavior for /secure/* (or similar).
    • Under Restrict viewer access, choose to use Trusted key groups and select your new key group.

Step 3: Using Signed URLs

With your key group in place, your application backend can create signed URLs that grant clients temporary access to protected content.

Basic Elements of a Signed URL

  • CloudFront resource URL – e.g. https://cdn.example.com/secure/video.mp4
  • Policy – either:
    • Canned policy: simple expiration and optional IP limit
    • Custom policy: complex conditions (paths, date ranges, IPs)
  • Signature – generated by your private key
  • Key pair ID – identifies which public key CloudFront should use to verify

Example Flow

  1. User clicks a “Download” button in your web app.
  2. The server validates that the user is authorized for that asset.
  3. The server generates a signed URL with:
    • Short expiration time (e.g. 5–15 minutes)
    • Optional IP restriction to the user’s IP
  4. The client is redirected to or receives the signed URL and downloads content directly from CloudFront.

Key Advantages

  • Fine-grained control per file
  • Human-shareable links that expire quickly
  • Simple integration for individual downloads or streams

Step 4: Using Signed Cookies

Signed cookies are better when you want to authorize access to a set of paths (e.g. /secure/*) without rewriting every link.

How Signed Cookies Work

  1. After the user logs in, your application checks their entitlements.
  2. The backend generates a set of cookies containing:
    • The policy (canned or custom), including expiration and restrictions
    • The signature over the policy
    • The key pair ID
  3. These cookies are sent back to the browser with a Set-Cookie header, typically scoped to your CloudFront domain, for example cdn.example.com.
  4. Subsequent requests to any matching path (like https://cdn.example.com/secure/image.jpg) automatically include the cookies.
  5. CloudFront validates the cookies and, if valid, serves content from the EC2 origin or cache.

Typical Use Cases

  • Members-only dashboards with many static assets
  • Premium image or video galleries
  • Multi-file download portals or course platforms

Step 5: Locking Down EC2 Behind CloudFront

To truly secure the path from CloudFront to EC2, you must prevent direct origin access.

Network-Level Controls

  • Security Groups / Firewalls:
    • Restrict inbound traffic to only:
      • The CloudFront IP ranges (complicated to maintain), or
      • Your load balancer or VPC endpoints used by CloudFront if using private connections.
  • Internal ALB / NLB:
    • Use an internal load balancer so the origin is not internet-routable.

Application-Level Validation

  • Custom headers from CloudFront:
    • Configure CloudFront to send a secret header, e.g. X-From-CloudFront: some-secret-value.
    • Configure your EC2 app or ALB rules to reject requests missing or mismatching this value.
  • OAuth / Session validation (optional):
    • For dynamic pages served directly from EC2 (not cached), still enforce user sessions and authorization.

Security Best Practices

  • Short-lived tokens: Keep signed URLs and signed cookie expirations as short as practical, especially for sensitive content.
  • Strong key management:
    • Rotate key pairs periodically.
    • Store private keys in AWS Secrets Manager, SSM Parameter Store, or KMS-backed solutions.
  • Least privilege:
    • Limit who and what can read your private key.
    • Use separate keys for different apps or environments.
  • Logging and monitoring:
    • Enable CloudFront access logs.
    • Monitor anomalies such as unusual geographic access or download volumes.
  • Custom error pages:
    • Return helpful 403 pages that guide users to log in or request access instead of generic error text.

Putting It All Together

By combining CloudFront signed URLs or signed cookies with tight control over your EC2 origins, you can implement a secure, scalable architecture for delivering private content. The general pattern is:

  1. Authenticate users in your main web app.
  2. Authorize access to specific content or paths.
  3. Issue signed URLs or signed cookies for CloudFront.
  4. Serve content from CloudFront, not directly from EC2.
  5. Lock down the EC2 origin so CloudFront is the only public entry point.

This provides a clean separation between authentication and content delivery while leveraging CloudFront’s global network, caching, and DDoS protection.

Further Reading

If you want to dive deeper into examples and implementation details, check out this related guide: CloudFront to EC2 Secure Paths with Signed Cookies and URLs.

```

Comments

Popular posts from this blog

Best CDN of 2025: Performance Benchmarks Across 15 Providers

CDN 77 Review: Latency Tests and Feature Walkthrough

OVH CDN Review 2025: Performance Tests Across Five Continents