Skip to content

Latest commit

 

History

History
82 lines (50 loc) · 5.52 KB

File metadata and controls

82 lines (50 loc) · 5.52 KB

Human-Not-Present Walkthrough

The intent-anchored human-not-present (HNP) AP2 scenario, end to end. The user is offline; the shopping agent operates under the authority of two open mandates the user issued in advance.

To regenerate the fixtures locally:

cargo run --example human_not_present_intent -- --out target/local-hnp
diff -r fixtures/scenarios/human-not-present target/local-hnp   # must be empty

Cast

Same three identities as the HP scenario (see human-present.md §Cast).

Step 1 — User issues OpenCheckoutMandate (SD-JWT VC)

The user issues an OpenCheckoutMandate constrained to:

  • LineItems (e.g. 2 × concert tickets close to main stage)
  • AllowedMerchants (the merchant identity the agent will transact with)

The mandate is wrapped as an SD-JWT VC signed by the user's Ed25519 key with a cnf JWK delegating to a per-session merchant delegate key. The root token is the file at fixtures/scenarios/human-not-present/open_checkout_token.json; the decoded mandate payload is open_checkout_mandate.json.

Step 2 — User issues OpenPaymentMandate (SD-JWT VC)

In parallel the user issues an OpenPaymentMandate constrained to:

  • AmountRange (currency + max + optional min) — the budget cap
  • AllowedPayees (the merchant identity)
  • PaymentReference (conditional_transaction_id = sha256(open_checkout_mandate_token)) — binds the payment to the checkout open mandate

The cnf JWK delegates to a per-session credentials-provider delegate key. Token: open_payment_token.json. Payload: open_payment_mandate.json.

Step 3 — Shopping agent presents to merchant

The shopping agent presents the open checkout mandate to the merchant. The merchant calls evaluate_intent (in crates/ap2-actors/src/merchant.rs) and either:

  • FulfillOpenMandates — the merchant has enough information to proceed without calling the user back into session, or
  • RequireUserInSession — the constraints aren't satisfied and the merchant rejects the intent.

In this scenario the merchant picks FulfillOpenMandates.

Step 4 — Merchant builds Checkout and closes the CheckoutMandate

The merchant assembles a Checkout payload (line items, totals, expiry, links) and computes a compact JWS over it (checkout_jwt). The closed CheckoutMandate carries:

  • checkout_jwt — the merchant-signed compact JWT
  • checkout_hashsha256_b64url(canonical_json(checkout_jwt))

The merchant then issues the closed CheckoutMandate as an SD-JWT extension on top of the user's open token, producing checkout_mandate_sd_jwt.json. The hop is joined with ~~; the cnf rotates from the user → merchant delegate.

Step 5 — Credentials provider closes the PaymentMandate

The credentials provider verifies the open payment mandate's SD-JWT, mints a closed PaymentMandate bound to the closed checkout's checkout_hash, and issues it as an SD-JWT extension producing payment_mandate_sd_jwt.json. The cnf rotates from the user → credentials-provider delegate.

Step 6 — Merchant payment processor settles

The MPP runs verify_and_settle (in crates/ap2-actors/src/mpp.rs):

  1. MandateClient::verify_chain on the checkout SD-JWT — walks every hop, checks per-hop cnf rotation, audience, nonce, expiry.
  2. CheckoutMandateChain::parse then verify — runs the AP2 constraint engine over the chain. Returns Vec<Violation>; an empty vec is the only success signal.
  3. MandateClient::verify_chain on the payment SD-JWT.
  4. PaymentMandateChain::parse then verify — checks line items, allowed payees, amount range, agent recurrence, budgets, payment-reference binding.
  5. Builds the CheckoutReceipt and PaymentReceipt, each carrying the prior-hop hash for offline replay.

Audit pack

The full audit pack is trace.json — same shape as the HP trace, recording every per-step input, digest, signer, and violation list.

Inspecting a chain by hand

ap2 chain inspect "$(cat fixtures/scenarios/human-not-present/checkout_mandate_sd_jwt.json | jq -r .token)"

prints each hop's decoded payload as JSON. Add --jwks fixtures/keys/jwks.json to also verify the issuer signature on every hop.