Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-hmac-framing-skill-9421-default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"adcontextprotocol": patch
---

Fix stale HMAC-as-recommended framing in reporting-webhook.json, auth-scheme.json, and create-media-buy-request.json's artifact_webhook; add RFC 9421 default guidance to call-adcp-agent SKILL.md. Description-only fixes aligning these surfaces with the existing push-notification-config.json framing (HMAC is the deprecated fallback, RFC 9421 is the default). No wire format changes.
19 changes: 19 additions & 0 deletions skills/call-adcp-agent/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,25 @@ When you see `status: 'submitted'`, the work is NOT complete. Poll via `tasks/ge

`budget` is a **number** (not `{amount, currency}` — currency is implied by the pricing option). Required per package: `product_id`, `budget`, `pricing_option_id`. `buyer_ref` is optional but strongly recommended as a buyer-side correlation id across retries and reporting.

### Webhook signing — omit `authentication` for new integrations

When you include `push_notification_config` in a request, do **not** set `authentication`
unless you are integrating with a legacy receiver. Omitting `authentication` selects the
default: the seller signs each inbound webhook POST with its RFC 9421
`adcp_use: "webhook-signing"` key, published at the `jwks_uri` in its own `brand.json`
`agents[]` entry. You verify against the seller's JWKS. No shared secret crosses the wire.

Presence of `authentication` is a **switch, not a fallback** — it opts the seller into
Bearer or HMAC-SHA256 and disables 9421 for that registration. A buyer MUST NOT attempt
"try 9421 first, fall back to HMAC" verification — mode is fixed at registration time.

The `authentication` block (Bearer / HMAC-SHA256) is deprecated and sellers MAY decline
to support it. It is removed in AdCP 4.0. The `token` field (a correlation token echoed
back in the webhook payload) is separate from `authentication` and is not deprecated.

See [Webhook callbacks](https://adcontextprotocol.org/docs/building/implementation/security#webhook-callbacks) for the
full verifier checklist and downgrade-resistance rules.

## Error envelope — read `issues[]` to recover

Every validation failure produces:
Expand Down
6 changes: 3 additions & 3 deletions static/schemas/source/core/reporting-webhook.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
},
"authentication": {
"type": "object",
"description": "Authentication configuration for webhook delivery (A2A-compatible)",
"description": "Legacy authentication configuration for webhook delivery (A2A-compatible). Opts the receiver into Bearer or HMAC-SHA256 signing. Both schemes are deprecated; the preferred signing profile for new integrations is RFC 9421, where the seller signs with a key published at its brand.json agents[] entry and the buyer verifies against the seller's JWKS — no shared secret crosses the wire (see docs/building/implementation/security.mdx#webhook-callbacks). This field is required in AdCP 3.x; the requirement is removed in AdCP 4.0 when the default RFC 9421 path becomes the only path.",
"properties": {
"schemes": {
"type": "array",
"description": "Array of authentication schemes. Supported: ['Bearer'] for simple token auth, ['HMAC-SHA256'] for signature verification (recommended for production)",
"description": "Array of authentication schemes. ['Bearer'] for simple token auth, ['HMAC-SHA256'] for legacy shared-secret signing. Both are deprecated; new integrations SHOULD use the RFC 9421 webhook signing profile instead.",
"items": {
"$ref": "/schemas/enums/auth-scheme.json"
},
Expand All @@ -30,7 +30,7 @@
},
"credentials": {
"type": "string",
"description": "Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.",
"description": "Credentials for the legacy scheme. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.",
"minLength": 32
}
},
Expand Down
2 changes: 1 addition & 1 deletion static/schemas/source/enums/auth-scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "/schemas/enums/auth-scheme.json",
"title": "Authentication Scheme",
"description": "Authentication schemes for push notification endpoints",
"description": "Legacy authentication schemes for the webhook auth block. Bearer: token sent in Authorization header. HMAC-SHA256: legacy shared-secret signing. Both are deprecated; new integrations SHOULD omit the authentication block and use the RFC 9421 webhook signing profile (applicable on schemas where authentication is optional). Removed in AdCP 4.0.",
"type": "string",
"enum": [
"Bearer",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@
},
"authentication": {
"type": "object",
"description": "Authentication configuration for webhook delivery (A2A-compatible)",
"description": "Legacy authentication configuration for webhook delivery (A2A-compatible). Opts the receiver into Bearer or HMAC-SHA256 signing. Both schemes are deprecated; the preferred signing profile for new integrations is RFC 9421, where the seller signs with a key published at its brand.json agents[] entry and the buyer verifies against the seller's JWKS — no shared secret crosses the wire (see docs/building/implementation/security.mdx#webhook-callbacks). This field is required in AdCP 3.x; the requirement is removed in AdCP 4.0 when the default RFC 9421 path becomes the only path.",
"properties": {
"schemes": {
"type": "array",
"description": "Array of authentication schemes. Supported: ['Bearer'] for simple token auth, ['HMAC-SHA256'] for signature verification (recommended for production)",
"description": "Array of authentication schemes. ['Bearer'] for simple token auth, ['HMAC-SHA256'] for legacy shared-secret signing. Both are deprecated; new integrations SHOULD use the RFC 9421 webhook signing profile instead.",
"items": {
"$ref": "/schemas/enums/auth-scheme.json"
},
Expand All @@ -158,7 +158,7 @@
},
"credentials": {
"type": "string",
"description": "Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.",
"description": "Credentials for the legacy scheme. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.",
"minLength": 32
}
},
Expand Down
Loading