fix: implement JCS cart-to-payment mandate binding per RFC 8785#251
fix: implement JCS cart-to-payment mandate binding per RFC 8785#251chopmob-cloud wants to merge 58 commits intogoogle-agentic-commerce:mainfrom
Conversation
This commit introduces the foundational elements of the protocol, including core data structures and documentation. Co-authored-by: Holt Skinner <holtskinner@google.com> Release-As: 0.1.0
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
[skip-changelog]
- Add Site Author - Add `site_dir` -> Possibly to fix `CNAME` overwriting issue - Add Life of a Transaction to Nav
* [Doc]: fixing typos in various files * [Doc]: reverting function name change for now * Fix spelling error `_log_request_instructions` --------- Co-authored-by: Holt Skinner <holtskinner@google.com>
…tic-commerce#40) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…gentic-commerce#50) Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…als (google-agentic-commerce#20) # Description s/Verifiable Credential/verifiable digital credential s/VC/VDC Fixes google-agentic-commerce#18 🦕 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
# Description - Align MPP acronym with glossary. Signed-off-by: Hyung-Kyu Choi <hyungkyu.choi@gmail.com>
…oogle-agentic-commerce#48) - Add optional Vertex AI authentication via `GOOGLE_GENAI_USE_VERTEXAI` environment variable - Update `run.sh` to check for either `GOOGLE_API_KEY` or `GOOGLE_GENAI_USE_VERTEXAI=true` - Fix `PaymentDetailsModifier` schema type from `Optional[Any]` to `Optional[dict[str, Any]]` for Vertex AI compatibility - Update `README.md` This enables users to authenticate using either: 1. `GOOGLE_API_KEY` (existing method) 2. `GOOGLE_GENAI_USE_VERTEXAI=true` with `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` (new Vertex AI method) Fixes google-agentic-commerce#47 🦕 --------- Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com> Co-authored-by: Holt Skinner <holtskinner@google.com>
…le-agentic-commerce#29) Implements logging for the X-A2A-Extensions header when present in incoming requests. This improves debugging visibility for A2A protocol extension usage. Resolves TODO in server.py:132 Fixes google-agentic-commerce#28 --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com>
…ios (google-agentic-commerce#80) ### Summary Adds a short "Install uv" section to the README pre-requisites section so newcomers don’t hit `uv: command not found`, for a better developer experience. ### Why Scenario run scripts depend on uv but the README doesn’t mention it yet. This update avoids onboarding friction. --------- Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
> [!TIP] > Better reviewed commit-by-commit. # Description Implements a standalone `go` sample. - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/google-agentic-commerce/AP2?tab=contributing-ov-file#how-to-contribute). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [x] Ensure the tests and linter pass - [x] Appropriate docs were updated (if necessary) Closes google-agentic-commerce#71 🦕
Define v.01 PaymentReceipt schema and demonstrate its creation and flow between agents. This brings the sample code in alignment with section 7.1 of the [specification](https://github.com/google-agentic-commerce/AP2/blob/main/docs/specification.md).
Correct sorting and add endorsing partners who should have already been included.
correct url for Nexi on partner
…ples (google-agentic-commerce#121) This PR introduces support for the x402 payment method within the Python human-in-the-loop agent scenarios. It enables the simulation of x402-compatible transactions across the Merchant, Shopping, and Payment Processor agents. Key Changes: - Documentation: Added a detailed README.md for the x402 scenario, including setup and execution instructions. - Scripting: Updated run.sh to accept a --payment-method argument (defaulting to CARD). - Merchant Agent: - Updated catalog_agent.py to generate CartMandate artifacts with x402 specific PaymentMethodData when enabled. - Updated tools.py to route x402 payments to the correct processor. - Payment Processor Agent: - Enhanced tools.py to handle PAYMENT_METHOD environment variable. - Implemented logic to process x402 payment mandates, skipping the OTP challenge and credential provider lookup where appropriate (using mock/dummy clients). - Added logic to generate x402-specific payment receipts. - Shopping Agent: - Updated tools.py to co nstruct PaymentMandates with the correct method_name and details for x402. - Updated payment_method_collector/tools.py to mock x402 payment payloads when the payment method is set to x402. - Credentials Provider Agent: - Added a mock "x402_wallet" to the `account_manager.py`. - Updated tools.py to recognize https://www.x402.org/ as a supported method. --------- Co-authored-by: Jordan Ellis <jordanellis@google.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Set of changes for Jan docs.
…gle-agentic-commerce#138) This commit adds an article discussing how UCP and AP2 protocols relate to one another. --------- Co-authored-by: Holt Skinner <13262395+holtskinner@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Update uvlock repository to the public `https://pypi.org/simple` registry. Fixes google-agentic-commerce#145
# Description Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/google-agentic-commerce/AP2?tab=contributing-ov-file#how-to-contribute). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [x] Ensure the tests and linter pass - [x] Appropriate docs were updated (if necessary) adding a link of UCP with ap2. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: GarethCOliver <GarethCOliver@users.noreply.github.com>
# Description Release v.2 spec, create HNP samples & python SDK, update existing DPC example & HP examples. Co-authored-by: @GarethCOliver Co-authored-by: @natalie-ngan Co-authored-by: @prateekdudeja19-g Co-authored-by: @kmcduffie Co-authored-by: @reema7 Co-authored-by: @jorellis Co-authored-by: @joshlund-goog Co-authored-by: @mdoeseckle
# Description update the title of the video on the main README
…merce#240) Clarified contribution guidelines regarding the core specification and focus on samples and SDK. # Description Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Follow the [`CONTRIBUTING` Guide](https://github.com/google-agentic-commerce/AP2?tab=contributing-ov-file#how-to-contribute). - [ ] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - [ ] Ensure the tests and linter pass - [ ] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕
# Description Update the CHANGELOG.md
# Description Removing uv.lock
Addresses the CartMandate <> PaymentMandate binding gap raised in google-agentic-commerce#211. ## Spec (docs/ap2/specification.md) Added section "Cart-to-Payment Mandate Binding" under Payment Mandate with three normative requirements: 1. PaymentMandateContents MUST include cart_mandate_id and cart_mandate_hash = hex(sha256(JCS(CartMandate))) per RFC 8785. JCS eliminates cross-language float-serialisation ambiguity (Python: 120.0, Go: 120 — different bytes without canonicalisation). 2. cart_mandate_hash MUST be computed with null/None optional fields excluded so Python and Go (omitempty) produce the same canonical form. 3. Verifiers MUST recompute the hash and MUST reject on mismatch before releasing credentials or initiating payment. ## Types (code/sdk/python/ap2/models/mandate.py) Added two Optional fields to PaymentMandateContents: - cart_mandate_id — reference to the bound CartMandate. - cart_mandate_hash — sha256(RFC 8785 canonical form of CartMandate). Both Optional for backward compatibility; new mandates SHOULD populate both. ## Sample validation (code/samples/python/src/common/validation.py) New helper module with: - validate_payment_mandate_signature() — placeholder for sd-jwt-vc key-binding verification (unchanged from prior design). - validate_cart_mandate_hash() — recomputes and compares the JCS hash. Uses model_dump(exclude_none=True) so None-valued optional fields are omitted, matching Go omitempty and ensuring cross-language consistency (high-priority Gemini feedback on the earlier closed PR google-agentic-commerce#241). Uses f-strings throughout (low-priority Gemini feedback). ## Dependency (code/samples/python/pyproject.toml) Added rfc8785>=0.1.2 for RFC 8785 JSON canonicalisation.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request implements the cart-to-payment mandate binding as specified in AP2 section 4.1.3.1. It introduces the rfc8785 dependency, updates the PaymentMandateContents model to include cart_mandate_id and cart_mandate_hash fields, adds validation logic in a new utility module, and updates the specification documentation. I have no feedback to provide.
Addresses cspell and markdownlint failures in CI: - validation.py: serialised→serialized, behaviour→behavior, authorised→authorized (cspell uses American English dictionary) - specification.md: same spelling fixes + serialisation→serialization, canonicalisation→canonicalization, authorises→authorizes - specification.md: fix pre-existing MD030 violations (3 spaces after list markers → 1 space) exposed by touching the file - .cspell/custom-words.txt: add fastmcp, omitempty, rfc8785 (pre-existing package name and Go struct tag used in pyproject.toml and the new validation comments)
|
I have read and signed the Google CLA. @googlebot please re-check. |
[Agent Authorization Framework][agent_authorization.md] used a reference-style label with no corresponding link definition, triggering markdownlint MD052. Convert to an equivalent inline link. Pre-existing issue exposed by touching the file.
ac7a12a to
dfcb25b
Compare
|
Reopening this work as #253 — the branch on this PR was inadvertently broken during a local history-cleanup pass and GitHub auto-closed it. The replacement carries the identical code, cherry-picked clean onto current |
Summary
Closes the CartMandate ↔ PaymentMandate binding gap raised in #211.
The core problem: without a cryptographic link from
CartMandatetoPaymentMandate, a malicious or misconfigured agent can substitute a different cart after the user has expressed intent. The fix uses RFC 8785 (JSON Canonicalization Scheme) to produce a deterministic hash that is consistent across Python, Go, and TypeScript implementations.Spec (
docs/ap2/specification.md)New normative section Cart-to-Payment Mandate Binding under §Payment Mandate with three requirements:
PaymentMandateContentsMUST includecart_mandate_idandcart_mandate_hash = hex(sha256(JCS(CartMandate))).null/Noneoptional fields so Python and Go (omitempty) produce identical canonical bytes.Types (
code/sdk/python/ap2/models/mandate.py)Added two
Optionalfields toPaymentMandateContents:cart_mandate_id— reference to the boundCartMandate.cart_mandate_hash—hex(sha256(JCS(CartMandate))).Both are
Optionalfor backward compatibility; new mandates SHOULD populate both.Sample validation (
code/samples/python/src/common/validation.py)New helper module containing:
validate_payment_mandate_signature()— placeholder for sd-jwt-vc key-binding.validate_cart_mandate_hash()— recomputes and compares the JCS hash. Usesmodel_dump(exclude_none=True)for cross-language consistency (matches Goomitempty); raisesValueErroron mismatch; skips with a warning ifcart_mandate_hashis absent (backward-compatible rollout).Dependency (
code/samples/python/pyproject.toml)Added
rfc8785>=0.1.2.Test plan
validate_cart_mandate_hash()returns without error when hash matches.validate_cart_mandate_hash()raisesValueErrorwhen the hash does not match.validate_cart_mandate_hash()logs a warning and returns cleanly whencart_mandate_hashisNone(backward compat).PaymentMandateContentswith both new fields round-trips through Pydantic serialisation without error.