Skip to content

fix: align mandate types with spec for HNP security#202

Open
gautammanak1 wants to merge 1 commit intogoogle-agentic-commerce:mainfrom
gautammanak1:fix/mandate-security-spec-alignment
Open

fix: align mandate types with spec for HNP security#202
gautammanak1 wants to merge 1 commit intogoogle-agentic-commerce:mainfrom
gautammanak1:fix/mandate-security-spec-alignment

Conversation

@gautammanak1
Copy link
Copy Markdown

  • Add IntentMandate id, user_authorization, and Pydantic validation for unsigned vs cart-confirmation rules
  • Add PaymentMandateContents intent_mandate_id, TransactionModality enum, and HNP validation requiring intent reference
  • Bind payment signing to intent mandate hash when present; populate modality and intent_mandate_id from shopping agent state
  • Sync Go sample structs; clarify Cart Mandate dual-signature wording in specification; fix IntentMandate JSON example in a2a-extension

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:

Fixes 150🦕

@gautammanak1 gautammanak1 requested a review from a team as a code owner March 29, 2026 13:19
@google-cla
Copy link
Copy Markdown

google-cla bot commented Mar 29, 2026

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.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for 'Human Not Present' (HNP) transaction flows by updating mandate specifications and sample implementations. Key changes include adding unique identifiers and user authorization fields to IntentMandate, introducing a TransactionModality enum, and ensuring payment mandates are cryptographically bound to pre-authorized intent mandates. Feedback focuses on refining the logic for including intent hashes in signatures, improving consistency in placeholder hash generation, and correcting multiline string formatting in Pydantic models.

@gautammanak1 gautammanak1 force-pushed the fix/mandate-security-spec-alignment branch from 6a131e3 to e3501b4 Compare March 29, 2026 13:25
- IntentMandate: id, user_authorization, Pydantic validation for unsigned vs
  cart-confirmation rules
- PaymentMandateContents: intent_mandate_id, TransactionModality enum, HNP
  validation requiring intent_mandate_id when human_not_present
- Shopping agent: bind payment signing to signed intent only; intent hash uses
  intent_mandate.id; modality and intent_mandate_id from state
- Go sample structs; specification and a2a-extension doc updates
- Ruff: ignore UP017 for Python 3.10; spellcheck and cspell hygiene
- CI: set LINTER_RULES_PATH and MARKDOWN_CONFIG_FILE (.markdownlint.json in
  .github/linters); disable MD060 for wide tables
@gautammanak1 gautammanak1 force-pushed the fix/mandate-security-spec-alignment branch from be32686 to a477afa Compare March 29, 2026 13:36
@gautammanak1
Copy link
Copy Markdown
Author

Hello @holtskinner @jorellis

I’m Gautam Manak (@gautammanak1). This contribution aligns the AP2 reference implementation with the specification for mandate security, with a focus on Human Not Present (HNP) flows.

What problem this addresses
The specification describes Intent Mandates as user-signed where HNP applies, and Payment Mandates as bound to both Cart and Intent so the payments ecosystem can reason over agentic, HNP transactions. The codebase did not fully reflect that: key fields and binding logic were missing or incomplete, which could mislead anyone using this repo as the source of truth.

What I changed

IntentMandate: Added a stable id, optional user_authorization (JWT in real deployments; a dev placeholder in samples), and Pydantic validation so an unsigned intent cannot be combined with “no per-cart confirmation” in an invalid way.
PaymentMandateContents: Added intent_mandate_id and TransactionModality (human_present / human_not_present), with validation so human_not_present requires an intent_mandate_id.
Shopping agent sample: When an intent is present and user-signed, the payment mandate carries the right modality and intent reference; sign_mandates_on_user_device only appends an intent mandate hash when intent_mandate.user_authorization is set, and the placeholder hash uses intent_mandate.id for consistency with the other fake hashes.
Go sample types, documentation (clearer Cart Mandate signing story), spellcheck / markdown hygiene, and CI: pointed super-linter at the repo’s real markdownlint config so Lint Code Base matches the project’s intended rules.
How it behaves

Human-present flows: signing is driven by cart + payment hashes; an unsigned intent in state does not add an intent hash to the authorization string.
HNP with a signed intent: the payment side can reference the intent (intent_mandate_id, human_not_present), and the user authorization string includes the intent binding only when the intent is actually signed, matching the spec’s security story.

Thank you to the Google team and AP2 maintainers for maintaining this project and for reviewing this change.

Best regards,
Gautam

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Security Inconsistencies Between Specification and Implementation in Mandate Design

1 participant