docs: add normative verifier obligation for checkout_hash#243
docs: add normative verifier obligation for checkout_hash#243chopmob-cloud wants to merge 8 commits intogoogle-agentic-commerce:mainfrom
Conversation
Verifiers (Credential Provider, Merchant, MPP) are required to recompute checkout_hash from the raw checkout_jwt bytes and reject the mandate on mismatch. This obligation was implicit in the field definition but absent as normative MUST text, leaving implementations free to skip the integrity check before releasing credentials or initiating payment.
There was a problem hiding this comment.
Code Review
This pull request updates the documentation for the Checkout Mandate to include a mandatory verification step for the checkout_hash. The reviewer suggested rephrasing the new requirement for improved readability and clarity, which has been accepted as a valid improvement opportunity.
| Before releasing credentials or initiating payment, the Credential Provider, | ||
| Merchant, and Merchant Payment Processor each MUST independently recompute | ||
| `checkout_hash` by applying the `_sd_alg` algorithm (or `sha-256` if absent) | ||
| to the raw bytes of the `checkout_jwt` value and comparing the result to the | ||
| `checkout_hash` field. If the values do not match, the verifier MUST reject | ||
| the mandate and MUST NOT proceed with the transaction. |
There was a problem hiding this comment.
For improved readability, consider rephrasing this paragraph to more clearly separate the primary requirement from the implementation details. Breaking the first long sentence into two can make the instruction easier to parse.
| Before releasing credentials or initiating payment, the Credential Provider, | |
| Merchant, and Merchant Payment Processor each MUST independently recompute | |
| `checkout_hash` by applying the `_sd_alg` algorithm (or `sha-256` if absent) | |
| to the raw bytes of the `checkout_jwt` value and comparing the result to the | |
| `checkout_hash` field. If the values do not match, the verifier MUST reject | |
| the mandate and MUST NOT proceed with the transaction. | |
| Before releasing credentials or initiating payment, the Credential Provider, | |
| Merchant, and Merchant Payment Processor each MUST verify that the `checkout_hash` | |
| field's value matches a computed hash of the `checkout_jwt` value. The hash | |
| MUST be computed by applying the `_sd_alg` algorithm (or `sha-256` if absent) | |
| to the raw bytes of the `checkout_jwt` value. If the values do not match, the | |
| verifier MUST reject the mandate and MUST NOT proceed with the transaction. |
MD030: normalize list-marker spacing (- -> -) MD036: replace bold-as-heading with proper ##### heading MD031: add blank lines around fenced code blocks MD007/MD032: remove indentation from inline example lists and add surrounding blank lines MD040: add 'text' language tag to encoded-token code blocks MD012: remove consecutive blank lines MD026: remove trailing period from section heading spellcheck: disable cspell around base64-encoded token examples
Replace three scattered inline cspell:disable comments with one block wrapping the entire Examples section, which contains all base64 nonces, encoded tokens, and example product identifiers that the spellchecker flags.
MD001: downgrade Example headings from h5 to h4 to maintain heading-level increments under h3 section headings MD030: normalize ordered list marker spacing (1. -> 1.) gitleaks: add .gitleaks.toml allowlist for docs/ to suppress false positives on example SD-JWT tokens
…ath) Super-linter reads gitleaks config from .github/linters/.gitleaks.toml, not the repo root. Move the allowlist there so example SD-JWT tokens in docs/ are correctly suppressed.
Split the single long sentence into two shorter sentences to more clearly separate the primary requirement (verify the hash matches) from the implementation detail (how to compute the hash). Addresses Gemini code-review feedback on PR google-agentic-commerce#243.
|
Thanks for the suggestion @gemini-code-assist — applied in the latest commit. The paragraph now opens with the primary obligation ("verify that the |
|
That sounds great. Thank you for confirming the update, and I'm glad the phrasing now clearly emphasizes the normative obligation for verifiers. |
Summary
The
checkout_hashfield definition incheckout_mandate.mdspecifies whatthe field IS (base64url SHA-256 of
checkout_jwt) but contains no normativeobligation telling verifiers they MUST check it.
This adds a MUST/MUST NOT gate immediately after the field description:
Motivation
Without this text, a conformant implementation can accept a Checkout Mandate
where
checkout_jwthas been substituted (e.g. amount altered) whilecheckout_hashstill matches the original. The field provides no securityguarantee until checking it is normatively required.
This follows the pattern already established in the
payment.referenceconstraint evaluation ("MUST contain an open Checkout Mandate with a matching
hash") — the same MUST language applied to the Checkout Mandate's internal
integrity gate.
Related: issue #211 (cart-to-payment binding discussion).