Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Align agent resolution and webhook pin checks with AdCP 3.3 (adcp#7882)

Open
#548 2 comments 0 reactions 0 assignees View on GitHub

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

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

claude-triaged cross-repo

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

  1. Match the agent by canonical URL, never by type or id alone.
    • Canonicalize the agent URL and every candidate agents[].url per docs/reference/url-canonicalization. Exactly one entry must match.
    • This applies to webhook verification and governance iss, which used to compare byte-for-byte. The capabilities verifier_constraints.agent_url_match is now canonical.
    • A type or id filter may narrow the match. It must never be the selector.
  2. House Portfolio operator records.
    • Candidates are house.agents[] plus every brands[].agents[].
    • Matches that agree on type and on the resolved JWKS source count as one entry. Otherwise more than one match is request_signature_brand_json_ambiguous.
  3. 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 the identity.key_origins check.
    • 3.x fallback: if the field is absent, use /.well-known/brand.json at 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 specific request_signature_* cause.
  4. Publisher signing_keys pin: 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 kid alone is not enough. A pinned entry without complete public-key parameters matches nothing, and revoked_at still 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_origins is no longer skipped for pinned keys.
    • resolveAgent has no publisher context, so this lives in the webhook verifier. The API probably needs a way to pass the applicable pins in.
  5. Origin-binding fallback. Read authorized_operators[] only from a House Portfolio. Any entry whose domain equals the agent's eTLD+1 passes. Its brands/countries don't scope key resolution.
  6. Governance JWS.
    • Match iss canonically against exactly one type: "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.json from its host.
  7. 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.

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_origins mismatch 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from adcontextprotocol/adcp-go

All issues in adcontextprotocol/adcp-go

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.