Align agent resolution and webhook pin checks with AdCP 3.3 (adcp#7882)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- go
- Domain
- backend-api-design, security
Research direction
Start with adcp/signing/jwks_fetcher.go and adcp/v3/signing/jwks_fetcher.go, then read the webhook verifier and ResolveAgent alongside the AdCP 3.3 agent-resolution reference. Check the linked spec PR for the algorithm, since the spec text is still pending merge. Done means implementing the in-scope canonical resolution, webhook key discovery and pin checks, governance matching, and cache rules, with tests for the listed newly failing signatures; TMP key handling is explicitly out of scope.
Written by the indexing model from the issue text.
Description
Likely touch points: adcp/signing/jwks_fetcher.go and adcp/v3/signing/jwks_fetcher.go, adcp/webhook, and ResolveAgent as described in the spec's reference implementations section. TMP key handling (tmproto, router/registry.go) is out of scope: the new algorithm excludes TMP.
adcontextprotocol/adcp#7882 adds one Agent resolution algorithm to docs/building/by-layer/L1/security.mdx (anchor #agent-resolution). It changes how verifiers match an agent and pick its keys. The change is a minor protocol change for AdCP 3.3 (main is in 3.3 beta). Spec text is on that PR until it merges.
What verifiers need to change
- Match the agent by canonical URL, never by type or id alone.
- Canonicalize the agent URL and every candidate
agents[].urlperdocs/reference/url-canonicalization. Exactly one entry must match. - This applies to webhook verification and governance
iss, which used to compare byte-for-byte. The capabilitiesverifier_constraints.agent_url_matchis nowcanonical. - A
typeoridfilter may narrow the match. It must never be the selector.
- Canonicalize the agent URL and every candidate
- House Portfolio operator records.
- Candidates are
house.agents[]plus everybrands[].agents[]. - Matches that agree on
typeand on the resolved JWKS source count as one entry. Otherwise more than one match isrequest_signature_brand_json_ambiguous.
- Candidates are
- Webhook key discovery starts from
identity.brand_json_url.- Fetch the seller's
get_adcp_capabilities, then run discovery steps 1–7: origin binding, canonical match, and theidentity.key_originscheck. - 3.x fallback: if the field is absent, use
/.well-known/brand.jsonat the agent's host, or at its eTLD+1 when the host serves none. Skip the steps that need the field (2, 3 and 7). - Webhook resolution failures report
webhook_signature_key_unknown. Log the specificrequest_signature_*cause.
- Fetch the seller's
- Publisher
signing_keyspin: narrowing intersection.- This replaces the old rule, where the pin was authoritative and the JWKS advisory.
- For a sell-side signature about publisher P's inventory, accept a key only if the agent's JWKS publishes it and its RFC 7638 thumbprint matches an entry in P's pin.
- Matching by
kidalone is not enough. A pinned entry without complete public-key parameters matches nothing, andrevoked_atstill applies. - Take the applicable publishers from the verifier's own record of the media buy, never from the payload. When several publishers apply, the key must match every pin.
- Before final rejection, force-refresh
adagents.json. key_originsis no longer skipped for pinned keys.resolveAgenthas no publisher context, so this lives in the webhook verifier. The API probably needs a way to pass the applicable pins in.
- Origin-binding fallback. Read
authorized_operators[]only from a House Portfolio. Any entry whosedomainequals the agent's eTLD+1 passes. Itsbrands/countriesdon't scope key resolution. - Governance JWS.
- Match
isscanonically against exactly onetype: "governance"entry. - Pick the collection the way the brand-authorization cross-check's step 2 does, using the governed request's brand domain. Never a sibling brand's.
- For signed requests, the buyer's brand.json is the exact operator record that agent resolution selected. Don't refetch
/.well-known/brand.jsonfrom its host.
- Match
- Cached mappings.
- A cached or onboarding mapping from agent URL to brand.json must have come from, or been re-confirmed against, the agent's
brand_json_url. - Re-confirm at least as often as the brand.json cache lifetime.
- A cached or onboarding mapping from agent URL to brand.json must have come from, or been re-confirmed against, the agent's
Signatures that newly fail (worth tests)
- A pinned key that the agent's JWKS doesn't publish.
- A pin entry with only a
kid. - A
key_originsmismatch on a pinned webhook key. - Two
agents[]entries that differ only by host case or default port, which are now ambiguous.
The brand-response cross-check and designated-task authorship check are unchanged.
🤖 Generated with Claude Code
- Dominant language
- Go
- Stars
- 4
- Forks
- 2
- Avg merge
- 20h 28m
- Merged PRs (30d)
- 24
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from adcontextprotocol/adcp-go
-
CreativeInput carries no revision_id or localization (follow-up to #545)Possibly taken @sujanchalla0510 claimed this 10 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
adcontextprotocol/adcp-go#567 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 38/100
adcontextprotocol/adcp-go#597 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
adcontextprotocol/adcp-go#590 ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 30/100
adcontextprotocol/adcp-go#588 · 3 comments ·
Maintainers usually reply within 1 day
-
Replace the hand-written RFC 9421 layer in adcp/v3/signing with httpsign and httpsfvPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 5/5 Over a week Newbie friendliness 25/100
adcontextprotocol/adcp-go#579 ·
Maintainers usually reply within 1 day
All issues in adcontextprotocol/adcp-go
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 78/100
slavakurilyak/awesome-ai-agents#880 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
apache/openserverless#282 · 2 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
agent-butler-finding bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
jordansmall/spindrift#6161 ·
Maintainers usually reply within 1 day