Skip to content

skills(call-adcp-agent): document RFC 9421 as default webhook signing path#4275

Closed
EvgenyAndroid wants to merge 1 commit intoadcontextprotocol:mainfrom
EvgenyAndroid:4270-skill-webhook-signing-on-ramp
Closed

skills(call-adcp-agent): document RFC 9421 as default webhook signing path#4275
EvgenyAndroid wants to merge 1 commit intoadcontextprotocol:mainfrom
EvgenyAndroid:4270-skill-webhook-signing-on-ramp

Conversation

@EvgenyAndroid
Copy link
Copy Markdown

Second leg of the two-PR shape proposed in #4270 (storyboard / SDK-skill on-ramp inventory). Pairs with #4273 (schema-description fix for reporting-webhook.json + auth-scheme.json) — independent landing order, both close pieces of #4270.

Why

The five protocol skills (adcp-media-buy, adcp-creative, adcp-signals, adcp-governance, adcp-si, adcp-brand) all defer cross-cutting buyer-side basics with:

Buyer-side basics — idempotency replay, oneOf variants, async status:'submitted' polling, error recovery from adcp_error.issues[] — live in skills/call-adcp-agent/SKILL.md.

That skill teaches idempotency_key, the account oneOf, status:'submitted' polling, and error recovery — but was silent on webhook signing. New buyers reading push-notification-config.json see a visible authentication field and reach for it; the modern 9421 default (omit the block, verify against the seller's JWKS) is invisible from the schema alone. That's the silent-default trap I called out in #4270 inventory.

This PR adds a section to the cross-cutting skill so all five protocol skills inherit the framing.

What this PR does

Single new H3 in skills/call-adcp-agent/SKILL.md titled "Webhook signing — default to RFC 9421, don't reach for authentication", placed inside "Non-obvious rules every buyer must follow" right after the async-polling section. Covers:

  • Default 9421 path — seller publishes a webhook-signing key at brand.json agents[].jwks_uri; buyer verifies via that JWKS; no shared secret on the wire.
  • Switch-not-fallback rule (per schemas(push-notification-config): state legacy/9421 precedence in authentication field #2506) — presence of push_notification_config.authentication selects legacy; absence selects 9421. Buyer MUST NOT attempt try-9421-then-HMAC verification.
  • Inbound verifier checklist — required covered components (@method, @authority, @target-uri, content-type, content-digest — all required on webhooks; no policy branch); tag=\"adcp/webhook-signing/v1\"; adcp_use=\"webhook-signing\"; error taxonomy webhook_signature_*.
  • Conformance vectors — pointer at compliance/{version}/test-vectors/webhook-signing/ as the only deterministic path to cover every webhook_signature_* error code.
  • "Use the SDK's verifier" — explicit nudge against rolling your own; RFC 9421 canonicalization is the dominant interop-bug surface (cross-references the canonicalization-bug language already in request-signing/README.md).

Plus a changeset entry mirroring the convention from #2506.

What this PR does NOT do

Test plan

Cross-references

I have read the IPR Policy

… path

The five protocol skills all delegate cross-cutting buyer-side basics to
call-adcp-agent/SKILL.md. That skill was silent on webhook signing, leaving
SDK consumers with no signal that omitting push_notification_config.authentication
selects the modern RFC 9421 path — a new buyer reading the schema sees a
visible authentication field and reaches for it.

Adds a "Webhook signing — default to RFC 9421, don't reach for authentication"
section to the cross-cutting skill, mirroring the framing locked in by adcontextprotocol#2506
on push-notification-config.json:

- Default 9421 path (seller publishes JWKS at brand.json agents[].jwks_uri,
  buyer verifies — no shared secret on the wire)
- Switch-not-fallback rule: presence of authentication selects legacy;
  absence selects 9421
- Inbound verifier checklist: required covered components, tag, adcp_use,
  error taxonomy
- Conformance test vectors as the only deterministic path to cover every
  webhook_signature_* error code
- Use the SDK's verifier; don't roll your own — canonicalization is the
  dominant interop-bug surface

No normative change. Pairs with schema-description fix in adcontextprotocol#4273. Closes
the SDK-skill sub-item of adcontextprotocol#4270.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@EvgenyAndroid
Copy link
Copy Markdown
Author

I have read the IPR Policy

@EvgenyAndroid
Copy link
Copy Markdown
Author

Deferring to #4271 per @bokelley's triage comment on #4270#4271 covers the same call-adcp-agent surface atomically with the schema fixes, targets 3.0.x correctly, and is tighter than mine (catches the token-not-deprecated cut + the "sellers MAY decline to support" normative line that I missed). Closing this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant