Skip to content

Read the Prebid EID cookie in the Prebid crate - #1382

Open
jwrosewell wants to merge 38 commits into
feature/40-rsc-flightfrom
feature/41-prebid-eids
Open

jwrosewell wants to merge 38 commits into
feature/40-rsc-flightfrom
feature/41-prebid-eids

Conversation

@jwrosewell

@jwrosewell jwrosewell commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Changes

Area Change
crates/trusted-server-core/src 15 files, 1072 lines added, 969 removed
crates/auction/prebid 2 files, 402 lines added, 0 removed
docs/superpowers 1 file, 106 lines added, 0 removed
docs/guide 5 files, 49 lines added, 22 removed
crates/trusted-server-adapter-fastly/src 2 files, 4 lines added, 13 removed
CHANGELOG.md 1 file, 1 line added, 0 removed
crates/trusted-server-adapter-axum/src 1 file, 1 line added, 0 removed
crates/trusted-server-adapter-cloudflare/src 1 file, 1 line added, 0 removed
crates/trusted-server-adapter-spin/src 1 file, 1 line added, 0 removed

Closes

Closes #1337

Spec

Spec: identifier-modules

Test plan

CI on this pull request at e3ec48c passed all 29 checks.

  • cargo test-fastly && cargo test-axum
  • cargo clippy-fastly && cargo clippy-axum
  • cargo fmt --all -- --check
  • JS tests: cd crates/trusted-server-js/lib && npx vitest run
  • JS format: cd crates/trusted-server-js/lib && npm run format
  • Docs format: cd docs && npm run format
  • WASM build: cargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1
  • Manual testing via fastly compute serve
  • Other: the full workflow set of this repository, run on this pull request at e3ec48c

Checklist

  • Changes follow AGENTS.md conventions
  • No unwrap() in production code (clippy denies unwrap_used in CI)
  • Uses log macros as AGENTS.md asks (not println!)
  • New code has tests
  • No secrets or credentials committed

On top of the Flight rewriter series (#1381). Issue: #1337.

What this adds

What changes.

The Prebid crate reads the cookie its script writes. Core's parser of the ts-eids cookie, with the cookie's name, its two shapes and its size limit, leaves crates/trusted-server-core/src/ec/prebid_eids.rs for crates/auction/prebid/src/eids.rs, and core declares one interface through which a module hands core the identifiers it learned for a request.

How it works.

  • An identifier module. IdentifierModule in core's ec/identifiers.rs has the shape of the prefix, geo and device interfaces: an id, the permissions it requires, and identifiers(call) answering the identifiers for a request or that the call was withheld. A registration offers one through with_identifier_module, the registry claims each id once, and the request's services carry the modules beside the geo, Edge Cookie and device modules on every adapter.
  • Core keeps the identity graph. Core asks the modules once at Edge Cookie read time, after the permissions are assembled and only when an Edge Cookie module is selected, holds the answer on the Edge Cookie context, syncs it into the identity graph as before (the body's identifiers first, the shared id cookie last), and offers it to the auction as the fallback when the request body carries none.
  • The Prebid crate owns the cookie. Its name is eids under the public prefix, the 8 KiB raw limit and both shapes are the crate's, and both Prebid builders register the module. Core names no cookie.
  • The template cache keys on the prefix. With no cookie name to list, the template cache refuses to key on any cookie under the public prefix, the shared id cookie included, where it refused a fixed list before.

Why

Every vendor's code leaves core and core keeps the interface. The identity graph is core's, and the cookie that feeds it from one vendor's script is the vendor's. The shared id cookie stays in core because it is not that cookie, has three other readers, and would otherwise be forwarded in bid requests where today it reaches the identity graph alone.

What breaks

A subresource request now decodes the cookie where before only navigations and the auction endpoints did, with persistence gated exactly as before. The template cache's identity rule is by prefix rather than by name, so a document keyed on another prefixed cookie is refused. trusted_server_core::ec::prebid_eids and the Fastly adapter's pre-routing cookie extraction are gone.

The commits

  1. The Prebid crate reads the cookie its script writes.
  2. A merge of the series below, which carries the fixes made lower in the stack.
  3. A merge of the series below, which carries the page origin change.
  4. The identifier modules design states what asking on every read costs and what stops loading, and takes its round 2 corrections.
  5. Later merges of the series below carry Tech Lab main at 6ef07ae.

What is not in this pull request

The Eid type and ec/eids.rs stay where they are for the OpenRTB series, which moves the protocol's types out of core.

Core parsed the `ts-eids` cookie the Prebid page script persists the
browser's identifiers in, in both shapes the script has written and with
the size limit the script applies, so core knew one vendor's cookie and
the Prebid crate did not own the cookie its own script writes.

Core now declares `IdentifierModule`, in `ec::identifiers`, through which
a module hands core the identifiers it learned for a request. A
registration offers one with `with_identifier_module`, the registry hands
every running registration's module to each request's services, and core
asks them once, when it reads the Edge Cookie state, where the request's
evidence is in hand. The answers are carried on the `EcContext` to
response finalization, which offers them to the identity graph after the
request body's own EIDs as the cookie was, and to the auction, which
forwards them when the body carries none. With no Edge Cookie module
selected nothing can hold or forward an identifier, so none are asked.

The Prebid crate owns the cookie's name, its two shapes, its size limit
and the parser in `eids.rs`, and `PrebidEids` is the first identifier
module, registered from the Prebid builder. `COOKIE_EIDS` leaves core, the
Fastly adapter no longer extracts the cookie before routing, and
`ec_finalize_response` no longer takes its value. The template cache's
identity rule refuses a key cookie under the public prefix instead of
naming the Edge Cookie and the EIDs cookie, because every cookie under
the prefix is one reader's own state.

The `sharedId` cookie stays in core. It is not the cookie this change is
about, and folding it into what a module hands core would forward it in
bid requests, where today it reaches the identity graph alone.
# Conflicts:
#	CHANGELOG.md
…and what stops loading

Review round 1 found that core asks the identifier modules on every read
of the Edge Cookie state, so the Prebid cookie is decoded on requests
that never use it, that the four adapters and their untested wiring were
not described, that the template cache rule now refuses key cookies that
loaded before, and that the opening gave the script's size limit where
core accepts 8 KiB and the script writes 3072 bytes. The design now
states each, adds the adapter table, the joins with no test and the open
questions, and records the review round.

One sentence of the Edge Cookies guide and one cell of the integration
guide now say when the modules are asked.
Round 2 approved the design with no blocking issues. The design now says
that a cookie in the shape the script writes today is tried as the
legacy shape first, that the request body drops an entry whose source
name is over 255 bytes and does not cut it, and which requests are
answered before the modules are asked, being closed paths on every
adapter and the script bundle on Axum, Cloudflare and Spin. The header
names the fork and Tech Lab draft pull requests and the pull request
that holds every design document of the stack.

The paragraph of the integration guide on identifier modules now names
the `[ec] module` condition and the client information and geo that the
call carries.
@jwrosewell
jwrosewell added this pull request to stack #1401 October 15, 2026 17:56
Comment thread crates/trusted-server-core/src/ec/identifiers.rs Fixed
@jwrosewell
jwrosewell removed this pull request from stack #1401 October 15, 2026 20:51
Comment thread crates/trusted-server-core/src/ec/identifiers.rs Fixed
Comment thread crates/trusted-server-core/src/ec/identifiers.rs Fixed
The two debug lines for an EID that gives no partner update printed the
EID's source, which is what the reader's cookie or request body carried.
The line for an EID with no partner now says only that one was skipped,
and the line for an EID with no valid uid names the partner by its
configured domain. A test captures both lines at debug level, so the
test log helper now keeps lines at a level its caller chooses, and
logged_by still keeps warnings and above.
Two test modules answered the name they were built with, read from their
own field, while every real identifier module answers a constant. A
module's name is what core passes to its call and logs when the module
contributes nothing, so a name held in the module made those log lines
look as if they printed data the module was handed. The module the
identifier tests use now answers one constant name, which no test
checks, and the registry tests use an enum of their two named modules.
@jwrosewell
jwrosewell removed this pull request from stack #1408 October 18, 2026 20:15
@jwrosewell jwrosewell closed this Oct 18, 2026
@jwrosewell jwrosewell reopened this Oct 18, 2026
@jwrosewell
jwrosewell removed this pull request from stack #1418 October 19, 2026 16:30
@jwrosewell jwrosewell closed this Oct 19, 2026
@jwrosewell jwrosewell reopened this Oct 19, 2026
@jwrosewell
jwrosewell added this pull request to stack #1421 October 19, 2026 17:38
@jwrosewell jwrosewell changed the title The Prebid crate reads the cookie its script writes Read the Prebid EID cookie in the Prebid crate Oct 19, 2026
@jwrosewell
jwrosewell removed this pull request from stack #1421 October 19, 2026 18:29
@jwrosewell
jwrosewell added this pull request to stack #1422 October 19, 2026 19:20
@jwrosewell
jwrosewell marked this pull request as ready for review October 19, 2026 20:24

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Core parses Prebid's EID cookie

2 participants