Repository navigation
Description
Summary
The injected script calls the EC route with a same-origin POST when the CMP reports consent and on every later change, sends consent changes in order with one call in flight, letting a newer change replace a waiting one but never a waiting withdrawal, which later changes wait behind, discards a result overtaken by a newer consent change, removes the IDs it merged on a withdrawal, sends the TCF string and the GPP string (Sourcepoint's capture from #1535), copies a localStorage _pubcid_optout into the cookie, and merges the returned IDs into Prebid.
Part of #1558, server-side identity on every adapter. Plan ID T20, planned in wave 8 (MVP: Fastly and Axum); priority P1, size M. Design: spec; order and dependencies: plan.
Requirements
ID-9 EC route
A same-origin route, /_ts/api/v1/ec by default, lets the script Trusted Server injects into proxied pages report consent and receive identity, so a reader who consents after the page loads gets an EC on that page view instead of the next navigation. A POST whose Origin matches the page mints the EC when the reader has none and consent allows, creates the record, runs the providers as a navigation does, and sets ts-ec, the SharedID cookie and the mirror cookie on its own response. It carries the consent strings the script reads from the CMP, the TCF string from __tcfapi and the GPP string from __gpp (Sourcepoint's capture from #1535 where present), which replace the consent cookies for that request; a withdrawal expires ts-ec, the SharedID cookie and the mirror cookie and tombstones the record in that response. The POST answers with JSON holding exactly what WB-4 would put in the mirror cookie for that request, and the SharedID only under SID-2 and SID-6; the script merges it into Prebid, and nothing else in the record reaches the page. A plain GET answers Prebid's SharedID pixelUrl with an empty 204: it never mints, calls a provider or changes consent, and only re-sets an existing SharedID cookie from the record (WB-3). The script sends consent changes in order with at most one call in flight. While a call is in flight, a newer change replaces a waiting one, except a waiting withdrawal, which is never replaced: later changes wait behind it. So every withdrawal reaches the server, after any grant in progress and before any later grant. The script discards a result that arrives while a newer consent change is waiting, and a withdrawal removes the IDs it merged into Prebid. Every response carries Cache-Control: no-store; a rate limit on the route waits with ID-6 (DEC-15). The route is served from the page's own host, which WebKit's cap on cookies from non-document responses exempts when the IP matches the page's (read from WebKit's source; the Accept tests it).
WB-6 Identity-only page script
A tsjs mode captures Prebid's IDs without the auction shim, reads the mirror cookie and merges the IDs into Prebid.
SID-2 Opt-out
A _pubcid_optout cookie stops SharedID reads, storage, sending, creation and write-back. Prebid also reads the opt-out from localStorage, which the server cannot see, so the injected script copies a localStorage _pubcid_optout into the cookie (T20).
Current state
What the code does today, from the design's survey at the revisions it names:
- ID-9: on main only a real-browser navigation through the publisher proxy mints an EC, and no such route exists. Extract existing Sourcepoint consent synchronization #1535 (RC line) posts Sourcepoint's GPP string to a separate, non-minting
/_ts/consentroute, wired into each adapter's router. - WB-6: the
ts-eidscapture runs only inside the shim, and nothing reads the mirror.
Acceptance criteria
- ID-9: On Fastly and Axum, a consented same-origin
POSTwith nots-eccreates the record and setsts-ecand the SharedID cookie in that response - ID-9: Its JSON omits a non-mirrored partner's ID, an ID whose vendor's TCF consent is denied and an expired ID
- ID-9: A withdrawal issued while a grant call with no EC and delayed providers is in flight leaves no identity cookie, no live record and no ID in Prebid
- ID-9: With grant A in flight, a withdrawal B and then a grant C reach the server as A, B, C, so B expires the identity cookies and tombstones A's record and C is handled as a first consent with no
ts-ec - ID-9: A cross-site
Origin, aGETand a client ID-7 refuses mint nothing and call no provider - ID-9: An unchanged returning reader gets no
Set-Cookie - ID-9: In Safari,
ts-ecand the SharedID cookie set by the route keep their one-yearMax-Ageon Fastly and on Axum behind CloudFront - WB-6: In that mode Prebid receives the mirrored IDs and no Trusted Server bidder is added to ad units
- SID-2: With
_pubcid_optoutpresent nothing SharedID-related is read, stored, sent, created or written, and a localStorage-only opt-out stops creation from the next request on
Dependencies
Blocked by:
- Identity-only tsjs mode #1594 Identity-only tsjs mode (new in this plan)
- EC route in the shared app, verified on Fastly #1598 EC route in the shared app, verified on Fastly (new in this plan)
Related pull requests
-
Extract existing Sourcepoint consent synchronization #1535 Extract existing Sourcepoint consent synchronization: carries part of this work.
Fixes the plan asks of Extract existing Sourcepoint consent synchronization #1535
Proposed closure, for the author to decide: Extract existing Sourcepoint consent synchronization #1535, Extract native EC lifecycle and DynamoDB persistence #1536 and Extract explicit EC storage selection and celld #1537 once T19, T20, A2 and A8 carry their code and tests.
Activity