Add the integration response-header hook and the provider documentation set - #1047
Open
jwrosewell wants to merge 5 commits into
Open
Add the integration response-header hook and the provider documentation set#1047jwrosewell wants to merge 5 commits into
jwrosewell wants to merge 5 commits into
Conversation
…ider First slice of the PR 838 decomposition (one PR per feature, Edge Cookie provider first). Introduces the EdgeCookieProvider trait and routes Edge Cookie minting, cookie read-back, and KV keying through the selected provider, so a vendor identifier round-trips verbatim instead of being dropped by the built-in shape check. - [ec] provider selector with per-provider [ec.providers.<key>] blocks; the hmac block carries the passphrase that previously lived on [ec]. With no provider selected, no Edge Cookie is generated. - Built-in provider: hmac (HMAC over client IP, preserves today's identity). The host-signal provider follows in the device slice, which supplies the host fingerprints it needs. - Request evidence abstraction (crate::evidence) giving providers read access to the client IP, headers (including cookies), URL path, and query parameters. - Adapter injection seam: RuntimeServices carries an optional vendor provider, so a vendor provider lives in its own crate and core never names it. - Provider-declared identifier semantics: accepts_id gates cookie read-back and withdrawal, normalize_id_for_kv controls the KV key, so an opaque identifier survives byte for byte as both cookie value and storage key. Tests cover the verbatim round-trip with a non-default provider, evidence access at generate time, and opaque KV persistence. Edge Cookie creation and use stay gated by the existing consent context exactly as before, including with no provider selected; the permission model replaces that input in a later slice. The client-set resolve path and the response-header hook are later slices. Config migration: [ec] passphrase is rejected as an unknown field; move it to [ec.providers.hmac] and select provider = "hmac" to keep minting.
jwrosewell
force-pushed
the
split/5-response-hook-docs
branch
from
August 20, 2026 01:47
35b9fbc to
e1926b7
Compare
…e provider Second slice of the PR 838 decomposition. Device classification and geolocation become selectable providers, mirroring the Edge Cookie provider seam: - [device] provider selects the classifier. The built-in default reads the User-Agent alone and makes no host call; the opt-in fastly provider strengthens the browser/bot gate with the host's TLS JA4 and HTTP/2 fingerprints (crates/device/fastly). - [geo] provider selects geolocation. No provider is the default and resolves no location; provider = "platform" opts into the host's lookup (crates/geo/fastly wraps the Fastly host lookup behind the PlatformGeo trait). - The host-signal Edge Cookie provider arrives with the capability it needs: the Fastly adapter injects the TLS/HTTP-2 fingerprints as a HostSignals service, and the provider mints from them plus the client IP. With no fingerprint at all it defers with a warning rather than degrading to an IP-only identifier. - Device signals move to a field-based DeviceSignals derived in the adapter (derive_ua_only for hosts without fingerprints). - The new crates join the fastly cargo aliases so they build, lint, and test in CI rather than compiling only transitively.
Third slice of the PR 838 decomposition. Permissions become the primitive that gates identity features; consent is one of several ways a permission is established: - permissions.rs resolves a per-request PermissionState from the country/region baseline in permissions.yaml augmented by the session's signals (TCF, GPP, GPC, US Privacy). Permission names follow the Privacy Taxonomy Data Uses. - The Edge Cookie gate moves from raw consent to the permission model: a provider declares required_permissions() and core executes it only when every one is set. With no provider selected the gate stays closed and identifiers are treated as absent, matching the stateless contract established in the first slice. - Withdrawal separates from mere not-permitted: ec_storage_withdrawn (an explicit signal) expires the cookie and writes tombstones, while a pre-consent or fail-closed state only strips EC response headers. - Bidstream EIDs gate on the permission model (gate_eids_by_permissions) instead of raw TCF consent. - [geo] default_country becomes required: it names the permissions.yaml rule that applies when the geo provider leaves a request unmatched, validated at startup, so there is always a defined permission baseline. - The consent module keeps building the ConsentContext; its EC-specific gating helpers move behind the permission model.
Fourth slice of the PR 838 decomposition. A provider that cannot derive an identifier at the edge can now defer, run its own page script, and mint from the value the page posts back: - POST /_ts/api/v1/ec/resolve accepts the client-produced value, runs it through the selected provider's resolve_from_client (which must verify it before trusting it), and sets the ts-ec cookie from the result. The endpoint enforces the provider's required permissions before the provider runs. - ClientFixedProvider is the built-in demonstration provider: it defers at the edge, its page script (ec_client_fixed) posts a fixed known word, and the endpoint mints when the word verifies. The script rides the tsjs bundle only when the provider is selected. - A test-only TestIdProvider models a client-minted UUID identifier and proves the full scenario: organic request defers, the client posts a value, the cookie is set, and the identifier round-trips verbatim on the next request. - EcContext keeps the injected provider and host signals for the request, so the resolve path rebuilds the provider with the same services as the organic path.
…on set Fifth and final slice of the PR 838 decomposition: - IntegrationResponseMutator lets an integration add headers (for example Accept-CH or detection-result headers) to outbound responses, applied on the platform-neutral response before the host adapter takes over. - Documentation for the provider model: configuration reference for the [ec], [device], and [geo] sections, the Edge Cookie guide rewritten around providers and the permission model, setup and error-reference updates, and the permission-model guide joins the docs navigation. - The Fastly EC lifecycle integration-test job joins the test workflow. - The example configuration documents every provider selector.
jwrosewell
force-pushed
the
split/5-response-hook-docs
branch
from
August 20, 2026 02:22
e1926b7 to
7ebce99
Compare
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.
Fifth and final PR decomposing #838 (see #1043 for the series description). Stacked on #1046: until predecessors merge, this PR displays the cumulative diff, so review the top commit only.
What this PR contains
IntegrationResponseMutatorlets an integration add headers (for exampleAccept-CHor detection-result headers) to outbound responses, applied on the platform-neutral response before the host adapter takes over.[ec],[device], and[geo]sections, the Edge Cookie guide rewritten around providers and the permission model, setup and error-reference updates, and the permission-model guide joining the docs navigation.With this PR merged, the five-PR series reproduces #838's head byte for byte (verified by merging the series in sequence and diffing the result against #838), and #838 can close as superseded.
Verification
Full gate green: fmt, clippy x6 with
-D warnings, all four adapters' test suites, cross-adapter parity. The combined series merged onto today's main also passes the full suite (1,984 core tests), with one prepared resolution where the cargo aliases overlap #1004.Produced with AI assistance under James Rosewell's direction; needs human review.