Skip to content

Grow origin_is_cookie_independent into a per-cookie template cache policy #1138

Description

@jevansnyc

Problem

origin_is_cookie_independent is all-or-nothing: either every cookie-bearing request bypasses the shared template cache (the default, which makes the cache nearly inert on real traffic because TS mints its own identity cookie), or all cookies are asserted irrelevant to origin HTML. Two common publisher deployment shapes cannot be expressed, and one of them makes a correct-looking config silently wrong.

Case 1: publisher A/B testing framework (motivating case)

A common topology: the publisher's CDN tier sits downstream of TS (it is TS's origin) and translates an experiment-bucket cookie (say ab_bucket) into a variant request header (say X-Exp-Variant) before the origin. The origin varies its HTML on that header and declares it in Vary.

The operator does the apparently correct thing:

origin_is_cookie_independent = true
template_cache_vary = ["x-exp-variant", ...]

But template_cache_vary keys on request headers as TS receives them from the browser, and the browser sends only the cookie. The variant header does not exist yet at TS's hop, so it keys as absent for every reader and all experiment arms collapse into one shared template. The origin's Vary: X-Exp-Variant counts as covered by the configured key, so the drift guard does not refuse storage. Result: cross-served experiment arms, with a config that reads as correct.

Case 2: small logged-in population

A mostly anonymous site with a small share of logged-in users whose account state is server-rendered. The operator wants those requests on the inline path and everyone else sharing templates. Today the only options are disabling sharing for everyone or asserting independence that is false for the logged-in slice.

Proposal

Grow the boolean into a per-cookie policy with three behaviors:

# Named cookies whose values join the template cache key (per-variant signals).
template_cache_key_cookies = ["ab_bucket"]

# Named cookies whose presence forces the inline path: no lookup, no store.
template_cache_bypass_cookies = ["session"]

# Unchanged meaning, now scoped: every cookie not named above is asserted
# irrelevant to origin HTML. Default false, unchanged.
origin_is_cookie_independent = true
  • Key cookies must be variant-shaped (bounded value sets: experiment arms, region buckets). Document that user-shaped identifiers do not belong in the key; the template stays reader-neutral and the key holds per-variant signals only, which is the existing key design rule.
  • Bypass cookies mirror the existing disqualification: presence of any named cookie sets cookie-disqualified for both lookup and store.
  • Unconfigured deployments are unchanged: conservative default, cache stays failing closed.
  • The Vary: Cookie drift guard is unchanged and still refuses regardless of policy.

Alternatives considered

  • Deriving a synthetic request header from the cookie before key derivation: equivalent power, but it invents a header namespace; putting the cookie name in the key config is more direct.
  • Keying on the full Cookie header: forbidden by design; every user is unique, so it is the per-user final-response cache under another name.

Relation to existing work

Follows the shared-template eligibility gate introduced with the ESI/C2 work and the authorization carve-out from #1070; this is the cookie-side equivalent of that carve-out.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions