Security Headers & Cookie Management in Hybrid AEM CDN Setup on AWS CloudFront

aemrules.com
Security Headers & Cookie Management in Hybrid AEM CDN Setup on AWS CloudFront
7 min read  ·  Anuj Gangwar  ·  AEM Architect @ Adobe
5 things to know in 30 seconds
1
Never manage security headers on both EDS and AMS independently — enforce all of them at CloudFront only using a Response Headers Policy. One place, consistent everywhere.
2
Your CSP policy must be a superset covering both EDS and AMS — scripts, fonts, and connect sources from both origins in one unified policy.
3
Strip ALL cookies before forwarding to EDS origin. EDS is stateless — forwarding AMS session cookies destroys cache efficiency and every user gets a unique cache entry.
4
For AMS authenticated paths, whitelist only the cookies you need — typically login-token. Never forward all cookies blindly.
5
For SSO across EDS and AMS pages, use a lightweight JWT shared cookie readable by EDS JavaScript client-side — never share the full AEM session cookie.
Ask a question in the Ask AI tab for more details on any topic.

 

Security Headers & Cookie Management in Hybrid AEM CDN Setup on AWS CloudFront

Introduction

When running a hybrid AEM setup with EDS and AMS behind a single AWS CloudFront distribution, security is more complex than a single-origin setup. You have two origins — each setting their own response headers, each with different cookie behaviour — and you need to present a consistent, secure experience to the end user regardless of which origin served the page.

Get this wrong and you end up with:

  • Inconsistent Content Security Policy (CSP) headers across EDS and AMS pages
  • AMS session cookies accidentally forwarded to EDS origin — destroying cache efficiency
  • Security headers set by AMS Dispatcher conflicting with headers set by CloudFront
  • Users losing their authenticated session when navigating from AMS pages to EDS pages

This post covers how to handle security headers and cookies correctly at the CDN layer.


The Fundamental Rule: Enforce Security Headers at CloudFront, Not at Origins

The biggest mistake teams make is trying to configure security headers independently on both origins:

  • Security headers set in Apache httpd.conf on AMS Dispatcher
  • Different or missing security headers on EDS (which has no Apache layer)

The result is inconsistent headers — the same CSP policy applies on /products/* but is missing or different on /blog/*.

The correct approach: enforce all security headers at CloudFront using a CloudFront Response Headers Policy. Strip security headers from both origins and let CloudFront be the single source of truth.

Both origins → CloudFront strips origin security headers
             → CloudFront Response Headers Policy applies
             → Consistent headers sent to every user
             regardless of which origin served the page

         

Security Headers to Manage at CloudFront Level

1. Content Security Policy (CSP)

CSP is the most complex header to manage in hybrid setups because EDS and AMS may load different third-party scripts, fonts, and assets.

The challenge:

  • AMS pages may load Adobe Analytics, Target, or other scripts
  • EDS pages may load Google Fonts, third-party embeds
  • A single CSP policy must cover both without being so permissive it becomes useless

Recommended approach:

Build a unified CSP that is a superset of what both origins need, and apply it at CloudFront level. In plain English:

Allowed script sources:
  - Your own domain (self)
  - Adobe Analytics / Launch domains
  - Google Tag Manager
  - Any third-party scripts used on either EDS or AMS pages

Allowed connect sources:
  - Your API endpoints
  - Adobe Experience Cloud domains
  - EDS hlx.live domain (if EDS fetches resources from hlx.live)

Block:
  - inline scripts (use nonces or hashes where needed)
  - object-src (always block Flash/plugins)
  - frame-src (whitelist only trusted embed domains)

Apply this as a CloudFront Response Headers Policy — it appends the CSP header to every response regardless of origin.


2. HSTS (HTTP Strict Transport Security)

HSTS tells browsers to always use HTTPS for your domain. This must be consistent across all paths.

Set this at CloudFront level only:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Remove it from AMS Apache/Dispatcher config entirely — if both set it, you get duplicate headers which some browsers reject.


3. X-Frame-Options and CSP frame-ancestors

Used to prevent clickjacking. Must be identical across EDS and AMS pages or the browser will behave inconsistently.

Set at CloudFront level:

X-Frame-Options: SAMEORIGIN

Or in modern setups, use CSP frame-ancestors directive instead (more flexible, replaces X-Frame-Options).


4. X-Content-Type-Options and Referrer-Policy

These are simple, consistent, and should be set once at CloudFront:

X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin

Cookie Management — The Most Critical Part

Cookies are where hybrid setups most commonly break. AMS is a stateful system that relies heavily on cookies. EDS is completely stateless. CloudFront sits between them and must make intelligent decisions about which cookies to forward to which origin.

The Problem in Plain English

Imagine a user logs into an AMS page (/products/checkout). AEM sets a session cookie:

login-token=abc123xyz

That cookie now lives in the user's browser. When they navigate to an EDS page (/blog/latest), their browser sends the same cookie with the request to CloudFront.

If CloudFront forwards that cookie to the EDS origin:

  • EDS ignores it (EDS is stateless and doesn't use cookies)
  • But the cookie is now part of the CloudFront cache key
  • Every authenticated user gets a different cache entry for the same EDS page
  • Your CloudFront cache hit rate for EDS drops to near zero
  • You are effectively serving EDS pages uncached — defeating the entire purpose of EDS

The Solution — Cookie Policies Per Cache Behaviour

In CloudFront you can define different cookie forwarding rules per path pattern.

For EDS paths — strip all cookies:

Cache Behaviour: /blog/*
Cookie forwarding: None
→ All cookies stripped before forwarding to EDS origin
→ Cache key is clean — all users share the same cache entry
→ EDS gets maximum cache efficiency

For AMS authenticated paths — forward specific cookies:

Cache Behaviour: /account/*  /checkout/*
Cookie forwarding: Whitelist
Forward only: login-token, JSESSIONID
→ AMS gets the cookies it needs for authentication
→ Cache is bypassed for these paths (or keyed by cookie value)

For AMS general content paths — forward no cookies:

Cache Behaviour: /products/*  /services/*
Cookie forwarding: None
→ AMS Dispatcher serves cached pages
→ No personalisation required on these paths
→ Maximum cache efficiency

SSO Across Origins — When a User Navigates Between EDS and AMS Pages

A common requirement: user logs in on an AMS page, then navigates to an EDS page. The EDS page should recognise the user is authenticated (e.g. show a personalised navigation).

The challenge: EDS cannot read AEM session cookies directly. It has no server-side session concept.

Recommended approach — JWT in a shared cookie:

User logs in on AMS (/account/login)
  ↓
AEM sets a lightweight JWT cookie (not the full session cookie):
  user-context=eyJuYW1lIjoiQW51aiJ9
  Domain: .example.com  ← shared across all subpaths
  HttpOnly: false        ← so EDS JavaScript can read it
  SameSite: Lax
  ↓
User navigates to EDS page (/blog/latest)
  ↓
EDS JavaScript reads user-context cookie
  ↓
Renders personalised navigation (Hello, Anuj)

This approach keeps the heavy AEM session cookie (login-token) server-side only while sharing a lightweight user context token that EDS JavaScript can use for UI personalisation.

CloudFront must be configured to:

  • Not forward user-context to EDS origin (EDS doesn't need it at origin — it's handled client-side)
  • Not include user-context in the EDS cache key (otherwise every user gets a unique cache entry)

Duplicate Header Problem — Stripping Origin Headers at CloudFront

Both AMS Dispatcher (Apache) and CloudFront can set the same security headers. If both set them, the user's browser receives duplicate headers — which can cause unexpected behaviour or browser rejections.

Solution — strip security headers at the origin before CloudFront adds them:

On AMS Apache/Dispatcher, remove these headers from httpd.conf:

# Remove these — CloudFront will set them
# Header always set Strict-Transport-Security ...
# Header always set X-Frame-Options ...
# Header always set Content-Security-Policy ...
# Header always set X-Content-Type-Options ...

On EDS — EDS does not have an Apache layer, so there is nothing to strip. CloudFront simply adds the headers on top of the EDS response.


Summary — What Goes Where

Header / Cookie Managed at Reason
CSP CloudFront Response Headers Policy Single unified policy for both origins
HSTS CloudFront Response Headers Policy Must be consistent, no duplicates
X-Frame-Options CloudFront Response Headers Policy Consistent clickjacking protection
X-Content-Type-Options CloudFront Response Headers Policy Simple, consistent
AMS session cookies (login-token) Forward to AMS paths only AMS needs them, EDS does not
EDS paths cookie forwarding Strip all cookies Protect EDS cache efficiency
User context JWT Client-side only (not forwarded) Shared identity signal for EDS JS

Key Takeaways

  • Never manage security headers independently on both origins — set them once at CloudFront and strip them from AMS Apache config entirely.
  • The CSP policy must be a superset of both EDS and AMS requirements — a single policy that covers all scripts, fonts, and connections used by either origin.
  • Cookie forwarding rules are the most critical configuration in hybrid setups — wrong cookie policies destroy EDS cache efficiency and can break AMS authentication.
  • Use a lightweight JWT shared cookie (not the full AEM session cookie) for SSO signals between AMS and EDS pages — EDS reads it client-side without needing it at origin.
  • Always use path-scoped cookie policies in CloudFront — EDS paths strip all cookies, AMS authenticated paths whitelist only what is needed.

Published on aemrules.com | Tags: AEM, EDS, AMS, CloudFront, Security Headers, CSP, Cookies, SSO, Hybrid AEM, CDN

Comments

Popular Posts

Configure/Decoding AEM AuditLogs

How to Increase Apache Request Per Second ?

AdobeDispatcherHacks ".statfile"

how to clear dispatcher cache in aem ?

How Does S3 works with AEM ?

AEM Security Headers

How to Sync HMAC in AEM ?

OakAccess0000: Access denied

AEM ACL and how they are evaluated

Dispatcher flush from AEM UI