docs(order): sign Webhook-Id, Webhook-Timestamp, and UCP-Agent in the webhook signature - #659
Open
vishkaty wants to merge 1 commit into
Conversation
… webhook signature The order event webhook lists Webhook-Id and Webhook-Timestamp as required headers and states that headers follow Standard Webhooks, but the signing and verification steps never cover them, and the example Signature-Input signs only method, authority, path, content-digest, and content-type. Webhooks carry no Idempotency-Key, so these headers are the only per-delivery replay signal; as written a captured, validly signed delivery can be replayed with an altered Webhook-Id or Webhook-Timestamp. The overview verification gate already anticipates this: a header outside the default covered set is gate-required when its defining section says so. Have the order webhook section say so for webhook-id and webhook-timestamp, require platforms to verify their coverage, and require deduplication on Webhook-Id. Update the signing and verification steps and the example accordingly. The example also now covers ucp-agent, which the overview gate already requires whenever the UCP-Agent header is present (it was missing from this example); this binds the signer identity on the webhook and subsumes the webhook-example change in Universal-Commerce-Protocol#568. Also drop the stale event_id and created_time from the example body and the playground payload builder (moved to headers in Universal-Commerce-Protocol#342), and show the required Webhook-Id and Webhook-Timestamp headers in the example.
vishkaty
force-pushed
the
fix/webhook-sign-standard-headers
branch
from
July 31, 2026 23:12
d05b53d to
f6f69b4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The order event webhook lists
Webhook-IdandWebhook-Timestampas required headers and states that headers follow Standard Webhooks, but the signing and verification steps never cover them, and the exampleSignature-Inputsigns only@method,@authority,@path,content-digest, andcontent-type.Webhooks carry no
Idempotency-Key, soWebhook-IdandWebhook-Timestampare the only per-delivery replay signal. As written, a captured, validly signed delivery can be replayed with an alteredWebhook-IdorWebhook-Timestamp, defeating any dedup or freshness check keyed on them.Fix
The overview verification gate is a closed set (
ucp-agent,signature-agent,idempotency-key) with the clause "a header added to UCP later is gate-required only if its defining section says so." This PR has the order webhook section say so:Webhook-IdandWebhook-TimestampMUST be covered components; platforms MUST verify their coverage and MUST deduplicate onWebhook-Id.Signature-Inputaccordingly.The example also now covers
ucp-agent. The overview gate already requires it whenever theUCP-Agentheader is present, and the example carried the header without covering it; adding it binds the signer identity on the webhook. This subsumes the webhook-example change proposed in #568 (that PR additionally coversucp-agentin a checkout-rest.md request example, which is left to it).It also drops the stale
event_id/created_timefrom the example body and the playground payload builder (moved to headers in #342), and shows the required headers in the example.Verification
validate_examples.pyanducp-schema lintunaffected (the change touches anhttpexample and prose, not validated JSON). PlaygroundeventId/eventTimeremain used elsewhere (no dead vars).