Repository navigation
Description
Summary
Identity on Cloudflare through T21's shared app with EZI-2c's store, passing T5's suite; build state once; drop the first-request Env capture and config block_on.
Part of #1558, server-side identity on every adapter. Plan ID T8, planned in wave 13 (after the MVP: Cloudflare); priority P2, size L. Design: spec; order and dependencies: plan.
Requirements
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-2 One shared record store
The identity logic stays in core and becomes awaitable (#1526). It runs on one EcKvStore over EdgeZero's KvStore (DEC-3). A store that cannot meet the contract makes startup reject identity configuration with a clear error.
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-5 After-response work
Only pull sync and guarded follow-up writes run after the response is sent: after send on Fastly, a task drained on SIGTERM on Axum, waitUntil on Cloudflare. On Spin the work runs before the response (DEC-14; DEC-16 rules out skipping it).
ID-8 Body EIDs keep being saved
EIDs sent in the /auction body are saved to the record.
WB-1 Document and EC route responses only
Identity cookies are set on top-level HTML document responses and on EC route responses (ID-9), on every supported adapter.
SH-1 Built once
Settings, the partner registry, store clients and the HTTP client are built once per process or isolate.
SH-3 No executor nesting
No block_on runs inside async code.
SH-4 No first-request capture
Cloudflare does not keep the first request's Env in a set-once thread_local.
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).
Current state
What the code does today, from the design's survey at the revisions it names:
- ID-8: main saves them on Fastly; the provider stack and the RC's Axum lifecycle do not.
- WB-1: main mints
ts-econ Fastly navigations, and the RC adds Axum. - 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. - SH-3: Make shared EC persistence awaitable #1526 wraps finalize in
block_on(Fastlymain.rs:550) and Collect server-side identity provider EIDs in a single page-load write #1487 callsblock_oninside finalize (main.rs:699), which panic together. Core pull sync and Cloudflare and Spin config reads also callblock_onon main; Make shared EC persistence awaitable #1526, Cut Trusted Server over to EdgeZero PR 275 #1506 and the RC remove the pull-sync one, RC commit933de5921removes Spin's, and Cloudflare's remains everywhere. - 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.
Acceptance criteria
- 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-2: No adapter crate's non-test code implements
EcKvStore, and a store reportingKvError::Unsupportedfor the contract fails startup with identity enabled - 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-5: On Fastly, Axum and Cloudflare a follow-up write recorded after send is in the record before the next navigation, and on Axum SIGTERM waits for it (A3). On Spin the follow-up write lands before the response
- ID-8: On each supported adapter a body EID is in the record after the request
- WB-1: Identity
Set-Cookieheaders appear on navigation and EC route responses and never on asset or other API responses - 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
- SH-3: The remaining
block_oncalls are only at adapter entry points - SH-4: Two requests with different
Envvalues each see their own - 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
Dependencies
Blocked by:
- One record backend over EdgeZero
KvStore; delete the Fastlyec_kv.rs#1587 One record backend over EdgeZeroKvStore; delete the Fastlyec_kv.rs(new in this plan) - Integration-branch tag with the Cloudflare parts edgezero#492 Integration-branch tag with the Cloudflare parts (new in this plan)
- Answer identify and batch sync locally on every adapter #1582 Answer identify and batch sync locally on every adapter (new in this plan)
- Identity conformance suite that runs against each adapter, Fastly and Axum first #1586 Identity conformance suite that runs against each adapter, Fastly and Axum first (new in this plan)
- One identity app in core for every adapter #1600 One identity app in core for every adapter (new in this plan)
Waits on these decisions:
- DEC-8 Cloudflare and Spin store (open). Which store Cloudflare and Spin use by default for the record: the DynamoDB or celld adapter, or a native store that meets the contract, per Platform support. Blocks EZI-2c, EZI-2s, R3, T8 and T9.
Blocks:
- Identity on Spin, the same scope as T8 #1589 Identity on Spin, the same scope as T8 (new in this plan)
- Identity features pass on Cloudflare from the shared app #1596 Identity features pass on Cloudflare from the shared app (new in this plan)
Notes from the plan
- The Cloudflare and Spin tickets (T8, T9, T17, T18, the EZI
candstickets, R3, R4, Cloudflare ClientInfo edgezero#91, As a developer I want to access client metadata in handlers edgezero#89 and "Blocked by" is set as a GitHub dependency between issues.
Activity
KvStore; delete the Fastlyec_kv.rs#1587