From the 2026-07 protocol security audit (registry NS-SIG-002; refs #3925).
Defect. The verify_brand_claim / verify_brand_claims response-signing verifier (docs/building/by-layer/L1/security.mdx:895-903) resolves kid→JWK at the agent's jwks_uri and checks adcp_use/alg/freshness/request_hash, but no step confirms the signing key is authorized for the claimed brand_domain. brand_domain and agent_url are attacker-chosen fields inside the payload the same key signs. Compare the governance JWS profile in the same file (:634), which explicitly warns that deriving identity from an unauthenticated in-token field is a circular trust chain.
Impact. An attacker running a conformant brand-agent for a domain it controls can emit a cryptographically valid owned response for brand_domain: "nike.com". The mutual-assertion floor (verify_brand_claim.mdx:23) bounds this — the attacker must control/forge both sides — but the signature the spec calls "load-bearing" attests authorship, not brand authority.
Decision to make. Add a normative verifier step mirroring governance step 13: fetch https://{brand_domain}/.well-known/brand.json (one redirect, SSRF-safe), confirm an agents[] entry with url == agent_url authorized for brand-protocol responses, and resolve kid only within that entry's jwks_uri. Treat brand_domain/agent_url as untrusted until this passes.
Enforcement to attach. A negative test vector: forged owned response for an unowned brand → expected: reject. Flip NS-SIG-002 to enforced on merge.
Part of the anti-drift lockdown (specs/spec-anti-drift.md). Rolls up to #3925.
From the 2026-07 protocol security audit (registry
NS-SIG-002; refs #3925).Defect. The
verify_brand_claim/verify_brand_claimsresponse-signing verifier (docs/building/by-layer/L1/security.mdx:895-903) resolveskid→JWK at the agent'sjwks_uriand checksadcp_use/alg/freshness/request_hash, but no step confirms the signing key is authorized for the claimedbrand_domain.brand_domainandagent_urlare attacker-chosen fields inside the payload the same key signs. Compare the governance JWS profile in the same file (:634), which explicitly warns that deriving identity from an unauthenticated in-token field is a circular trust chain.Impact. An attacker running a conformant brand-agent for a domain it controls can emit a cryptographically valid
ownedresponse forbrand_domain: "nike.com". The mutual-assertion floor (verify_brand_claim.mdx:23) bounds this — the attacker must control/forge both sides — but the signature the spec calls "load-bearing" attests authorship, not brand authority.Decision to make. Add a normative verifier step mirroring governance step 13: fetch
https://{brand_domain}/.well-known/brand.json(one redirect, SSRF-safe), confirm anagents[]entry withurl == agent_urlauthorized for brand-protocol responses, and resolvekidonly within that entry'sjwks_uri. Treatbrand_domain/agent_urlas untrusted until this passes.Enforcement to attach. A negative test vector: forged
ownedresponse for an unowned brand →expected: reject. FlipNS-SIG-002toenforcedon merge.Part of the anti-drift lockdown (
specs/spec-anti-drift.md). Rolls up to #3925.