spec(request-signing): protocol_methods_* namespace; widen test-agent strict route#4326
Conversation
…gent strict route Closes #4318: declares verifier coverage of JSON-RPC protocol methods (`tasks/cancel`, `tasks/get`) in a separate namespace from AdCP tool names. Schema enforces split via `pattern: "/"`; subset_of/disjoint_with mirror the AdCP-namespace rules. `identity.brand_json_url` is required_when any new field is non-empty. Normative text in security.mdx specifies that matches bind to the JSON-RPC `method` field and the same RFC 9421 covered components apply to JSON-RPC method calls. Closes #4314: test-agent `/<tenant>/mcp-strict` route enforces the new bucket. STRICT_REQUIRED_FOR widens to update_media_buy and sync_creatives so a buyer that signs the initial create but forgets follow-on mutations gets a 401 instead of a silent green light. STRICT_PROTOCOL_METHODS_REQUIRED_FOR adds tasks/cancel; new namespace-aware mcpOperationResolver returns the JSON-RPC method name for protocol methods (tasks/cancel, tasks/get) and the tool name for tools/call. Wire response from get_adcp_capabilities splits the bundle into the two namespaces; SDK-internal VerifierCapability stays flat (match is by-string-equality). The earlier #4314 X-Test-Require-Signing header proposal is not adopted (declaration-enforcement coherence, SDK singleton/eager-build constraints flagged in triage). Strict-route enforcement is the spec-coherent path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…space Follow-up to expert review on PR #4326: - Tighten schema `pattern` from `"/"` to `"^[a-z][a-z0-9_]*/[a-z][a-z0-9_]*$"` so `protocol_methods_*` items reject malformed strings like `/`, `tasks/`, or `tasks/cancel/extra`. Matches A2A 0.3.0 §7 single-slash family/verb conventions. - Add normative MUST in security.mdx: verifiers MUST NOT cross-namespace match (a `tools/call` body whose `params.name` matches a `protocol_methods_required_for` entry MUST NOT satisfy the match, and vice-versa). The two buckets are matched against disjoint envelope fields. - Add normative SHOULD in security.mdx: sellers populating `protocol_methods_*` on a transport that also serves `tools/call` SHOULD set `covers_content_digest: 'required'`. Without it, an on-path attacker who captures a signed `tools/call` can swap the body to `tasks/cancel` within the signature window. Sellers that cannot adopt 'required' MUST partition by `@target-uri`. - Harden `mcpOperationResolver` to enforce the cross-namespace MUST: a `tools/call` body with `params.name` containing `/` resolves to undefined (refuses the smuggled namespace), and a non-`tools/call` method without `/` resolves to undefined (defense-in-depth on the protocol-method side). - Add tests for cross-namespace refusal + `tools/call` with missing params. - Comment at the wire-shape splitter cross-references the schema constraint. Filed #4327 for the storyboard-vector gap (tasks/cancel negative vector). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Issue #4327 proposes adding Generated by Claude Code |
Expert review summaryThree reviews ran — Findings addressed in 0431d7a
Findings deferred
Verdict
Tests passing (368/368 vitest, 35/35 composed schema, 525 schemas valid, tsc clean). Will admin-merge once CI is green. |
|
Confirmed follow-up. The test plan already marks this Generated by Claude Code |
|
Fold recommendation withdrawn — #4327 is the right tracking surface for the Generated by Claude Code |
… protocol_methods_required_for Closes #4327. Adds negative vector that grades the `protocol_methods_required_for` namespace introduced in #4326: a verifier declaring `protocol_methods_required_for: ["tasks/cancel"]` but not enforcing it would silently accept an unsigned `tasks/cancel` POST. The vector POSTs an unsigned JSON-RPC body and asserts `request_signature_required` byte-for-byte. Capability-gated: runner skips when the agent doesn't declare the bucket; FAILs (not SKIPs) when it declares but doesn't enforce. Same shape as existing capability-gated negatives. No schema changes; no normative spec changes. Patch-eligible per the playbook (additive conformance scenarios). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… protocol_methods_required_for (#4335) Closes #4327. Adds negative vector that grades the `protocol_methods_required_for` namespace introduced in #4326: a verifier declaring `protocol_methods_required_for: ["tasks/cancel"]` but not enforcing it would silently accept an unsigned `tasks/cancel` POST. The vector POSTs an unsigned JSON-RPC body and asserts `request_signature_required` byte-for-byte. Capability-gated: runner skips when the agent doesn't declare the bucket; FAILs (not SKIPs) when it declares but doesn't enforce. Same shape as existing capability-gated negatives. No schema changes; no normative spec changes. Patch-eligible per the playbook (additive conformance scenarios). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
request_signing.protocol_methods_supported_for/_warn_for/_required_forso sellers can declare verifier coverage of JSON-RPC methods (tasks/cancel,tasks/get) separately from AdCP tool names. Schema enforces the namespace split viapattern: "/";subset_of/disjoint_withmirror the AdCP-namespace rules;identity.brand_json_urlisrequired_whenany new field is non-empty. Normative text added todocs/building/by-layer/L1/security.mdx./<tenant>/mcp-strictroute to enforce the new bucket.STRICT_REQUIRED_FORaddsupdate_media_buy+sync_creatives; newSTRICT_PROTOCOL_METHODS_REQUIRED_FOR = ['tasks/cancel']feeds a namespace-awaremcpOperationResolver(returnsparams.namefortools/call, themethodfield fortasks/*). Wire shape fromget_adcp_capabilitiessplits the bundle into the two namespaces; SDK-internalVerifierCapabilitystays flat (match is by-string-equality).The earlier #4314
X-Test-Require-Signingheader proposal is not adopted — declaration-enforcement coherence (security.mdx:927) and the SDK's singleton/eager-build authenticator architecture were both flagged in triage. Strict-route enforcement is the spec-coherent path that satisfies the originaltasks/cancel-on-abort regression-test ask in adcp-client#1617 Phase 2.minorchangeset per the playbook (signing profile changes are never patch-eligible).Test plan
npm run test:schemas(525 schemas validated)npm run test:composed— newrequest_signing.protocol_methods_*accept/reject cases passnpm run test:json-schema(256 docs JSON blocks validated)npx vitest run server/tests/unit/training-agent.test.ts(365/365)required_forand noprotocol_methods_*bucketsrequired_forandtasks/cancelinprotocol_methods_required_formcpOperationResolverhandlestools/call,tasks/cancel,tasks/get, malformed bodies, missing rawBodynpx tsc --noEmit -p server/tsconfig.json(clean)npm run test:storyboard-doc-parity(passes)tasks/cancelstep asserting verifier coverage matches declaredprotocol_methods_required_for🤖 Generated with Claude Code