Skip to content

fix(signatures): cover ucp-agent and signature-agent when signing - #785

Open
sakinaroufid wants to merge 1 commit into
Universal-Commerce-Protocol:mainfrom
sakinaroufid:fix/signatures-covered-components
Open

fix(signatures): cover ucp-agent and signature-agent when signing#785
sakinaroufid wants to merge 1 commit into
Universal-Commerce-Protocol:mainfrom
sakinaroufid:fix/signatures-covered-components

Conversation

@sakinaroufid

Copy link
Copy Markdown
Contributor

Description

The REST request signing pseudocode in signatures.md builds a component list that omits two components the verification pseudocode in the same document requires, so a signer written from it produces signatures the spec's own verifier rejects with coverage_insufficient.

Transcribing both routines and running the published signer against the published verifier:

default regime: POST with body
   published -> skip_signature(coverage_insufficient)   missing: ['ucp-agent']
   corrected -> PASS

WBA-shape regime: POST with body
   published -> skip_signature(coverage_insufficient)   missing: ['ucp-agent', 'signature-agent']
   corrected -> PASS

default regime: GET, no body
   published -> skip_signature(coverage_insufficient)   missing: ['ucp-agent']
   corrected -> PASS

Three problems in the same block:

  1. ucp_agent is tested on the component line but is not a parameter of sign_rest_request, and ucp-agent is missing from the headers dict passed to build_signature_base. Either way the component cannot be produced. UCP-Agent is required: true in both shopping/rest.openapi.json and common/rest.openapi.json, so verification demands ucp-agent coverage on every request, not just in an edge case.
  2. signature-agent is never added at all, although the signed-component table (footnote ***), WBA Interop step 3 ("MUST sign the signature-agent component with ;key="<label>"") and the verification routine all require it whenever the Signature-Agent header is present. Since that header designates the WBA key source, a signer following this pseudocode leaves the key source unbound.
  3. The body check reads body, but the parameter is body_bytes (used correctly a few lines above).

Worth being clear about the severity: the verification pseudocode is correct, so anyone implementing both halves from this document fails on the first round trip rather than shipping a signature gap silently. The cost is implementer time and conformance grading, not production insecurity.

This is also not a hypothetical class of problem. conformance/webhook_structure_test.py already had to stop grading ucp-agent coverage for the same reason:

# signatures.md's component table requires ucp-agent whenever the header
# is present, but order.md's own example webhook signature omits it; that
# inconsistency has a fix in flight (ucp#659). Until it lands, a merchant
# following the example verbatim must not be failed here.

#659 fixes the webhook example in shopping/order/index.md. It does not touch signatures.md, and it does not cover the signature-agent omission, so the request signing algorithm is still wrong after it lands.

No normative requirement changes here. The component table, the WBA Interop rules and the verification routine already agree on what must be covered; only the pseudocode disagreed with all three. signature-agent is ordered ahead of ucp-agent to match the worked Signature-Input example earlier in the same section, since that is the artifact implementers copy. RFC 9421 leaves component order to the signer, so the table's differing order is not wrong and is left alone.

Category (Required)

Please select one or more categories that apply to this change.

  • Core Protocol: Changes to the base communication layer, global context, or breaking refactors. (Requires Technical Council approval)
  • Governance/Contributing: Updates to GOVERNANCE.md, CONTRIBUTING.md, or CODEOWNERS. (Requires Governance Council approval)
  • Capability: New schemas (Discovery, Cart, etc.) or extensions. (Requires Maintainer approval)
  • Documentation: Updates to README, or documentations regarding schema or capabilities. (Requires Maintainer approval)
  • Infrastructure: CI/CD, Linters, or build scripts. (Requires DevOps Maintainer approval)
  • Maintenance: Version bumps, lockfile updates, or minor bug fixes. (Requires DevOps Maintainer approval)
  • SDK: Language-specific SDK updates and releases. (Requires DevOps Maintainer approval)
  • Samples / Conformance: Maintaining samples and the conformance suite. (Requires Maintainer approval)
  • UCP Schema: Changes to the ucp-schema tool (resolver, linter, validator). (Requires Maintainer approval)
  • Community Health (.github): Updates to templates, workflows, or org-level configs. (Requires DevOps Maintainer approval)

Categorised as Documentation because the change is confined to an illustrative code block and alters no normative requirement, no JSON schema and no operation behaviour. Happy to recategorise if maintainers read a correction to the reference signing algorithm as Core Protocol.

Related Issues

Related to #659, which fixes the same class of inconsistency in the order webhook example.

Checklist

  • I have followed the Contributing Guide (including Conventional Commits title requirements and ! for breaking changes).
  • I have updated the documentation (if applicable).
  • My changes pass all local linting and formatting checks.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • (For Core/Capability) I have included/updated the relevant JSON schemas.
  • I have regenerated Python Pydantic models by running generate_models.sh under python_sdk.

Notes on the unchecked boxes: there is no test surface for a pseudocode block in this repository, so no test was added. No JSON schema changed, so no model regeneration was needed.

Screenshots / Logs (if applicable)

pre-commit run --files docs/specification/signatures.md:

Validate JSON examples (changed docs)....................................Passed
cspell...................................................................Passed
trim trailing whitespace.................................................Passed
fix end of files.........................................................Passed
markdownlint.............................................................Passed

Full corpus example validation and link checking:

343 passed, 0 failed, 0 errors, 50 skipped
All internal links validated successfully.

The REST request signing pseudocode builds a component list that leaves
out two components the verification pseudocode requires, so a signer
written from it produces signatures the spec's own verifier rejects with
coverage_insufficient.

Three problems in the same block:

* `ucp_agent` is tested on the component line but is not a parameter of
  `sign_rest_request`, and `ucp-agent` is missing from the headers passed
  to `build_signature_base`. UCP-Agent is required on every request, so
  verification always demands `ucp-agent` coverage.
* `signature-agent` is never added, although the component table, WBA
  Interop step 3 and the verification routine all require it whenever the
  Signature-Agent header is present.
* the body check reads `body`, but the parameter is `body_bytes`.

Add the two parameters, append `signature-agent` with the `;key` label
used by the worked example above, and pass both headers through to the
signature base. No normative requirement changes here; this only makes
the example agree with the component table, the WBA Interop rules and the
verification routine.

The conformance suite currently skips grading `ucp-agent` coverage
because of the same class of inconsistency elsewhere in the spec (Universal-Commerce-Protocol#659).
@damaz91 damaz91 added the status:needs-triage Signal that the PR is ready for human triage label Aug 29, 2026
@carolinerg1 carolinerg1 added status:under-review and removed status:needs-triage Signal that the PR is ready for human triage labels Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants