Repository navigation
Description
Summary
One identity app in core for every adapter: mounts identify, batch sync, admin lookup and the EC route and runs the EC lifecycle in one router each adapter mounts, building its state once (SH-1); adapter crates supply platform services through EdgeZero where it offers them, and Fastly's limiter and geo stay their existing bridges until their asks land.
Part of #1558, server-side identity on every adapter. Plan ID T21, planned in wave 5 (MVP: Fastly and Axum); priority P1, size L. Design: spec; order and dependencies: plan.
Requirements
SH-5 One app for every adapter
The identity routes (identify, batch sync, admin lookup and the EC route), pull sync, the EC lifecycle, provider lookups and cookie write-back run from one app built in core, which every adapter mounts and which builds its state once (SH-1). An adapter crate supplies only platform services: through EdgeZero where it offers them, and otherwise through the adapter's existing platform bridge until the EdgeZero ask lands (today Fastly's limiter, ID-6, and Fastly's geo, EZI-4). A capability an adapter lacks is an EdgeZero ask, never new code in that adapter (DEC-16).
SH-1 Built once
Settings, the partner registry, store clients and the HTTP client are built once per process or isolate.
ID-1 One EC lifecycle
On every supported adapter a consented document navigation or EC route call (ID-9) mints the EC, creates the record and sets ts-ec together. A cookie is never issued without a record. An existing EC is kept when geo is unknown.
ID-3 Partner APIs answered locally
Identify, batch sync, pull sync and admin lookup run on every adapter with a record store. Without one, identify and batch sync return a local error and never reach the publisher origin. Admin lookup already answers 501 locally; pull sync is outbound only.
ID-6 Rate limiting (after the MVP, DEC-15)
In the MVP, Fastly keeps main's limits on batch sync and pull sync and #1487's per-provider lookup limit, and Axum has none because the deployer's load balancer limits traffic (DEC-11). Until EZI-5, Fastly's limiter stays the existing fastly::erl bridge in the Fastly adapter, and T21 keeps it when it moves the handlers into core. After the MVP, provider lookups, batch sync, pull sync and record creation are rate limited on every supported adapter except Axum, where every limit stays off by default; batch sync is keyed per partner and the other keys follow DEC-15, and an Axum limit turned on in configuration runs per task, divided by the configured task count.
Current state
What the code does today, from the design's survey at the revisions it names:
- SH-5: at Cut Trusted Server over to EdgeZero PR 275 #1506's head only the Fastly adapter wires identity (EC generation and finalization are called from its
app.rsandmain.rs); Axum, Cloudflare and Spin each build their own router without it. - SH-1: Cloudflare and Spin rebuild app state per request; Axum builds the partner registry per request (
app.rs:495at Cut Trusted Server over to EdgeZero PR 275 #1506's head9ec4711d3) and the HTTP client per request on purpose, because a pooled client regressed a Next.js flow (mainplatform.rs:620-623). Keep that client choice unless a measurement shows the regression gone. - ID-6: Fastly Edge Rate Limiting is the only limiter; record creation is limited nowhere; Collect server-side identity provider EIDs in a single page-load write #1487 keys lookups on the IP-derived EC prefix, so everyone behind one IPv4 address or IPv6 /64 shares a budget.
Acceptance criteria
- SH-5: No adapter crate's non-test code calls EC generation, finalization or an identity handler directly, and the same conformance suite (T5) runs on each supported adapter
- SH-1: An adapter test shows settings, the partner registry and store clients built once across two requests, and the HTTP client too, except Axum's, which stays per request until a measurement shows the Next.js regression gone
- SH-1: After that measurement Axum's client is held to the same rule
- ID-1: The conformance suite (T5) asserts on each supported adapter that a consented navigation creates the record and sets
ts-ecin the same response, that a store failure sets nots-ec, and that an existing EC survives unknown geo - ID-1: On an unsupported adapter, startup with identity configuration fails
- ID-3: In each adapter's tests a capturing origin receives no identify or batch-sync request
- ID-3: With a store they run, without one they return 501
- ID-6: In the MVP, Fastly's existing limits still refuse or skip over-limit requests after T21 and Axum's default configuration applies no limit
- ID-6: After the MVP, per-adapter tests hit each limit, and an Axum limit turned on for two tasks refuses at half the limit
Dependencies
Blocked by:
- Answer identify and batch sync locally on every adapter #1582 Answer identify and batch sync locally on every adapter (new in this plan)
- Cut Trusted Server over to EdgeZero PR 275 #1507 Cut Trusted Server over to EdgeZero PR 275
- PR Mirror provider EIDs to a cookie and run pull sync as an identity provider #1489 Mirror provider EIDs to a cookie and run pull sync as an identity provider
Blocks:
- Identity on Axum through T21's shared app #1574 Identity on Axum through T21's shared app (new in this plan)
- Identity on Cloudflare through T21's shared app with EZI-2c's store, passing T5's suite #1588 Identity on Cloudflare through T21's shared app with EZI-2c's store, passing T5's suite (new in this plan)
- Rate limits after the MVP #1590 Rate limits after the MVP (new in this plan)
- Providers in the shared app, awaited before finalization #1591 Providers in the shared app, awaited before finalization (new in this plan)
- Refuse record creation when a trusted JA4 contradicts the User-Agent #1592 Refuse record creation when a trusted JA4 contradicts the User-Agent (new in this plan)
- Create and write back SharedID in the shared app #1593 Create and write back SharedID in the shared app (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
-
Mirror provider EIDs to a cookie and run pull sync as an identity provider #1489 Mirror provider EIDs to a cookie and run pull sync as an identity provider: must merge first.
Fixes the plan asks of Mirror provider EIDs to a cookie and run pull sync as an identity provider #1489
Cap every mirrored ID's expiry at 30 days where the mirror is built (
mirror.rs:236-247), not in validation, because SID-5 keeps SharedIDNeverin the record. An unstated expiry still becomesExpiry::Never(coordinator/validate.rs:135-138), pull sync is its only production source (pull_sync.rs:145), and such IDs reach the cookie with noexpunder a one-yearMax-Age. The 30-day clamp on stated expiries comes from Add identity providers for ID5, LiveIntent, LiveRamp, ConnectID and UID2 #1488. Answer its open threads, including the one onany_dueskipping cookie-read opt-outs.
Notes from the plan
- Run server-side identity collection on the Axum dev server #1566 overlaps A2 and A10; its Axum part is rebuilt on T21 (Part C).
- T7, T14 and A11 are folded into A2 and A10, because the shared app (T21) brings partner APIs, the mirror cookie and the EC route to every adapter.
- Cut Trusted Server over to EdgeZero PR 275 #1507 delivers the cutover and stays under Integrate Auctioneer into Trusted Server on EdgeZero PR 275 #1505; it blocks A1, T4, T5, T21, Reduce Fastly adapter per-request fixed cost: defer KV/geo work, cache settings/registry/template fingerprint #1192 and Certificate checks on identity backends that still follow
proxy.certificate_check#1556.
Activity