Add TS admin endpoint to look up EC by id#928
Open
prk-Jr wants to merge 4 commits into
Open
Conversation
Adds GET /_ts/admin/ec/{id} (explicit EC ID) and GET /_ts/admin/ec
(EC ID from the caller's ts-ec cookie) so operators can inspect EC
identity graph entries and debug KV-to-auction EID propagation.
The core handler returns the stored KvEntry verbatim (including raw
consent strings and partner UIDs), the KV metadata mirror, the store
generation marker, and a derived auction view showing exactly which
EIDs the auction would attach and why each stored partner ID was
skipped (empty_uid, not_in_registry, bidstream_disabled). Corrupt
entries are returned with the parse error and raw body via the new
KvIdentityGraph::lookup_raw instead of failing closed.
The routes join Settings::ADMIN_ENDPOINTS so startup validation
rejects configs whose basic-auth handler regex does not cover them.
The EC identity graph is Fastly KV backed, so the Axum, Cloudflare,
and Spin adapters register the routes to local 501 responses, keeping
them off the publisher fallback that would forward the Authorization
header to the origin.
Closes #921
The dispatch arm reused EcRequestState::kv_graph, which is deliberately None for clients that fail the browser gate. Operators hit this auth-gated endpoint with curl, so every lookup returned 501 as if no EC store were configured. Build the identity graph directly from settings instead, and document why the bot-gated copy must not be used. Also point the bare-route no-cookie 404 at the explicit-id route, since the ts-ec cookie (Domain-scoped, Secure) cannot exist on localhost.
Adds GET /_ts/admin/eids, complementing the EC lookup endpoint with the client-side half of EID propagation: it decodes the request's ts-eids and sharedId cookies and previews what cookie ingestion would write into the EC entry's ids map — matched partner UIDs (deduplicated exactly like the ingestion path) and unmatched sources that would be dropped. The endpoint always responds 200; missing or malformed cookies are reported in the payload rather than as errors. It is pure request inspection with no KV access, so every adapter serves the real handler. The path joins Settings::ADMIN_ENDPOINTS for basic-auth coverage validation.
Review feedback on the admin EC lookup asked for readable dates. The echoed entry now carries derived created_iso and consent.updated_iso fields (yyyy-MM-ddTHH:mm:ss.SSSZ) next to the stored unix-seconds values, which stay untouched so the echo remains faithful to KV.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GET /_ts/admin/ec/{id}(explicit EC ID) andGET /_ts/admin/ec(EC ID from the caller'sts-eccookie) so operators can inspect EC identity graph entries without KV console access.empty_uid,not_in_registry,bidstream_disabled) — making KV-to-auction EID propagation debuggable in one call. Corrupt or legacy-schema entries stay inspectable via a new raw lookup that reportsentry_error+raw_bodyinstead of failing closed.GET /_ts/admin/eids, the client-side half of the picture: it echoes the request'sts-eidsandsharedIdcookies and previews what cookie ingestion would write into the EC entry'sidsmap (matched partner UIDs, deduplicated exactly like the ingestion path, plus dropped sources). Pure request inspection with no KV access, so every adapter serves the real handler; always responds 200.Changes
crates/trusted-server-core/src/ec/admin.rshandle_admin_ec_lookup+handle_admin_eids_lookuphandlers, response payload types, 14 unit testscrates/trusted-server-core/src/ec/kv.rsKvIdentityGraph::lookup_rawreturning raw body/metadata/generation without validationcrates/trusted-server-core/src/ec/prebid_eids.rspub(crate)so the EIDs preview reuses them instead of reimplementingcrates/trusted-server-core/src/ec/mod.rsadminmodulecrates/trusted-server-core/src/settings.rsSettings::ADMIN_ENDPOINTS; update coverage testscrates/trusted-server-adapter-fastly/src/app.rsec.kv_graph, so operator curl requests workcrates/trusted-server-adapter-axum/src/app.rsAdminEcNotSupported); EIDs route → real handlercrates/trusted-server-adapter-axum/tests/routes.rscrates/trusted-server-adapter-cloudflare/src/app.rscrates/trusted-server-adapter-cloudflare/tests/routes.rscrates/trusted-server-adapter-spin/src/app.rscrates/trusted-server-adapter-spin/tests/routes.rsCloses
Closes #921
Test plan
cargo test-fastly && cargo test-axum(alsocargo test-cloudflare && cargo test-spin)cargo clippy-fastly && cargo clippy-axum(alsoclippy-cloudflare,clippy-cloudflare-wasm,clippy-spin-native,clippy-spin-wasm)cargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest run(JS untouched — left to CI)cd crates/trusted-server-js/lib && npm run format(JS untouched — left to CI)cd docs && npm run format(docs untouched — left to CI)cargo check -p trusted-server-adapter-fastly --target wasm32-wasip1fastly compute serve: verified auth gating, the EC lookup against the seeded Viceroy entry, and the EIDs echo against real browser cookies; this surfaced (and the branch fixes) an initial bug where the bot-gated KV graph made curl requests return 501cargo test --manifest-path crates/trusted-server-integration-tests/Cargo.toml --test parity)Hardening note
All three paths were added to
Settings::ADMIN_ENDPOINTS, so startup validation fails closed (aConfigurationerror viaReport, nopanic!/unwrap()/expect()) for any config whose basic-auth handler regex does not cover them; prefix-style regexes like the example config's^/_ts/adminremain valid. Covered by the updateduncovered_admin_endpoints_*andadmin_endpoints_match_fastly_routertests. Routes are registered explicitly on every adapter so they never fall through to the publisher fallback, which would forward the caller'sAuthorizationheader to the origin.Checklist
unwrap()in production code — useexpect("should ...")logmacros (notprintln!)