diff --git a/doc/architecture/MPCP_IMPLEMENTATION_ROADMAP.md b/doc/architecture/MPCP_IMPLEMENTATION_ROADMAP.md index 269ae3be..885d9145 100644 --- a/doc/architecture/MPCP_IMPLEMENTATION_ROADMAP.md +++ b/doc/architecture/MPCP_IMPLEMENTATION_ROADMAP.md @@ -837,6 +837,42 @@ Implemented: `docs/` with overview (what-is-mpcp, problem, comparison-with-agent ⸻ +### PR18A — Protocol Chain Hero Diagram + +Add a canonical **MPCP Authorization Chain diagram** to the documentation homepage and architecture section. + +Diagram structure: + +PolicyGrant +→ SignedBudgetAuthorization +→ SignedPaymentAuthorization +→ Settlement + +Each layer visually represents how MPCP **progressively constrains machine spending authority**. + +Recommended labeling: + +• PolicyGrant — defines where and how a machine may pay +• SignedBudgetAuthorization — enforces session spending limits +• SignedPaymentAuthorization — authorizes a specific payment +• Settlement — records what actually happened + +Purpose: + +• give developers an immediate mental model of MPCP +• visually communicate the protocol’s constrained authorization chain +• establish a recognizable visual identity for MPCP documentation + +Deliverables: + +• SVG diagram included in docs/diagrams/ +• diagram embedded on the docs homepage +• diagram referenced in protocol overview pages + +This diagram becomes the **primary visual explanation of the MPCP protocol** and should appear early in the documentation to help new readers understand the authorization model quickly. + +⸻ + PR19 — Documentation Site Deployment ✓ Deploy the docs site so it is publicly accessible (e.g., GitHub Pages). Implemented: `mkdocs.yml`, `docs-requirements.txt`, `.github/workflows/deploy-docs.yml`. Enable GitHub Pages (Settings → Pages → Source: GitHub Actions) to publish. @@ -848,6 +884,24 @@ Purpose: ⸻ +PR20 — Golden Protocol Vectors ✓ + +Freeze a set of canonical MPCP test vectors for interoperability and regression testing. Implemented: `vectors/` (manifest.json, valid-settlement.json, expired-grant.json, budget-exceeded.json, intent-hash-mismatch.json, settlement-mismatch.json), `test/vectors/goldenVectors.test.ts`. + +Vectors: + • valid settlement (with intent hash) + • expired grant + • budget exceeded + • intent hash mismatch + • settlement mismatch (payment auth) + +Purpose: + • let other implementations validate compatibility + • prevent regressions + • create a real interoperability target + +⸻ + --- # Phase 6 — Adoption Acceleration @@ -1001,6 +1055,7 @@ Deliverables: • basic badge / claim format • documentation for how external implementations validate compatibility +⸻ # Expected Outcome diff --git a/doc/protocol/FleetPolicyAuthorization.md b/doc/protocol/FleetPolicyAuthorization.md index 4c10b250..16b55663 100644 --- a/doc/protocol/FleetPolicyAuthorization.md +++ b/doc/protocol/FleetPolicyAuthorization.md @@ -29,6 +29,8 @@ Fleet operators must ensure that vehicles only spend funds **within fleet‑defi FPA enables this capability by allowing fleets to issue **signed policy artifacts** that constrain all MPCP spending decisions. +> **Optional extension:** FleetPolicyAuthorization (FPA) is an optional MPCP artifact used by fleet operators to express higher-level fleet governance constraints. Base MPCP flows do not require FPA. + --- # 2. Problem Statement diff --git a/docs/animation/MPCP_ANIMATION_PACK.md b/docs/animation/MPCP_ANIMATION_PACK.md index 5f5918b6..ab9be39f 100644 --- a/docs/animation/MPCP_ANIMATION_PACK.md +++ b/docs/animation/MPCP_ANIMATION_PACK.md @@ -27,11 +27,15 @@ Narration: ## Scene 3 — Introducing MPCP Visual stack: +Fleet Policy +↓ PolicyGrant ↓ -BudgetAuthorization +SignedBudgetAuthorization (SBA) +↓ +SignedPaymentAuthorization (SPA) ↓ -PaymentAuthorization +SettlementIntent ↓ Settlement @@ -46,8 +50,8 @@ Narration: Visual sequence: 1. Autonomous vehicle enters parking garage 2. PolicyGrant appears -3. BudgetAuthorization appears -4. PaymentAuthorization triggers +3. SignedBudgetAuthorization (SBA) appears +4. SignedPaymentAuthorization (SPA) triggers 5. Settlement confirmation Narration: @@ -130,7 +134,7 @@ Protocol comparison diagram "clean animated diagram showing protocols MCP A2A ACP communicating between agents and tools, arrows moving between nodes, modern developer diagram style" ## Prompt 3 — MPCP Authorization Chain -"layered protocol diagram animation PolicyGrant BudgetAuthorization PaymentAuthorization Settlement blocks stacking vertically with glowing arrows" +"layered protocol diagram animation PolicyGrant SignedBudgetAuthorization SignedPaymentAuthorization SettlementIntent Settlement blocks stacking vertically with glowing arrows" ## Prompt 4 — Autonomous Parking Payment "autonomous car entering smart parking garage, digital authorization layers appearing around vehicle, futuristic payment confirmation animation" @@ -153,9 +157,11 @@ Icons - blockchain ledger Protocol blocks +- Fleet Policy - PolicyGrant -- BudgetAuthorization -- PaymentAuthorization +- SignedBudgetAuthorization (SBA) +- SignedPaymentAuthorization (SPA) +- SettlementIntent - Settlement Animation style diff --git a/docs/architecture/actors.md b/docs/architecture/actors.md new file mode 100644 index 00000000..897f3c81 --- /dev/null +++ b/docs/architecture/actors.md @@ -0,0 +1,76 @@ +# Actors + +MPCP defines several actor types that participate in machine payment flows. + +## Fleet Operator + +Owns and manages the autonomous fleet (vehicles, robots, agents). + +**Responsibilities:** + +- Defines vehicle payment policies +- Sets spending limits +- Restricts allowed vendors and locations +- Issues PolicyGrant artifacts + +**Examples:** Robotaxi fleet, delivery fleet, autonomous logistics fleet. + +## Vehicle Wallet (Machine Wallet) + +Resides in each machine (EV, robot, IoT device) and enforces MPCP constraints. + +**Responsibilities:** + +- Enforces policy constraints +- Manages charging/payment budgets +- Issues SignedBudgetAuthorization and SignedPaymentAuthorization +- Executes settlement transactions + +The wallet is the MPCP actor that signs SignedBudgetAuthorization and SignedPaymentAuthorization. + +## Service Provider + +The entity that receives payment for a service (parking, charging, tolls). + +**Responsibilities:** + +- Requests payment authorization +- Verifies MPCP artifact chain +- Provides or denies service based on verification + +**Examples:** Charging network operator, parking operator, toll system. + +## Route / Dispatch System + +(Optional) Determines routing and service requirements. + +**Responsibilities:** + +- Determines charging/parking locations along route +- Identifies approved service networks +- Provides trip metadata to the vehicle + +May influence PolicyGrant constraints. + +## MPCP Verifier + +Validates the full authorization chain. + +**Verification may occur:** + +- Inside the service provider backend +- Inside a dedicated MPCP verification service +- During post-transaction auditing + +## Settlement Rail + +Executes the actual payment. + +**Examples:** XRPL + RLUSD, EVM stablecoins, Stripe, hosted providers. + +MPCP does not replace settlement systems—it **controls authorization above them**. + +## See Also + +- [Reference Flow](reference-flow.md) — Full actor interaction in EV charging scenario +- [System Model](system-model.md) diff --git a/docs/architecture/artifact-lifecycle.md b/docs/architecture/artifact-lifecycle.md new file mode 100644 index 00000000..073a0ee7 --- /dev/null +++ b/docs/architecture/artifact-lifecycle.md @@ -0,0 +1,55 @@ +# Artifact Lifecycle + +MPCP artifacts flow through a defined lifecycle from policy evaluation to settlement verification. + +## Pipeline + +``` +Fleet Policy +↓ +PolicyGrant +↓ +SignedBudgetAuthorization +↓ +SignedPaymentAuthorization +↓ +SettlementIntent +↓ +Settlement +``` + +Each artifact constrains the next. Downstream artifacts must be subsets of upstream constraints. + +## Artifact Roles + +| Artifact | Issued By | Purpose | +|----------|-----------|---------| +| **PolicyGrant** | Fleet/service policy | Initial permission envelope; rails, assets, caps | +| **SBA** | Vehicle wallet | Session-level spending envelope | +| **SPA** | Vehicle wallet | Binds specific payment to quote and policy | +| **SettlementIntent** | Vehicle wallet | Canonical settlement description (optional hash in SPA) | +| **Settlement Result** | Settlement rail | Confirms execution | + +## Typical Lifecycle + +1. **Pre-session** — PolicyGrant issued and stored (fleet backend, vehicle wallet) +2. **Session entry** — Vehicle loads PolicyGrant, may issue SBA +3. **Payment request** — Service requests payment; vehicle validates policy and budget +4. **Authorization** — Vehicle creates SettlementIntent, signs SPA +5. **Verification** — Service verifies MPCP chain +6. **Settlement** — Payment executes on rail +7. **Reconciliation** — Settlement verified against authorization + +## Storage + +Artifacts may be stored in: + +- **Fleet backend** — Authoritative PolicyGrant; audit logs +- **Vehicle wallet** — Operational PolicyGrant, SBA, SPA, receipts +- **Service provider** — Received authorizations, verification results, receipts +- **Settlement rail** — Transaction record (authoritative) + +## See Also + +- [Reference Flow](reference-flow.md) — End-to-end EV charging scenario with timeline +- [Protocol specs](protocol/mpcp.md) — Full artifact specifications diff --git a/docs/architecture/authorization-chain.md b/docs/architecture/authorization-chain.md new file mode 100644 index 00000000..7b0c61f0 --- /dev/null +++ b/docs/architecture/authorization-chain.md @@ -0,0 +1,53 @@ +# MPCP Authorization Chain + +The **authorization chain** is the core visual model for MPCP. Each step produces a verifiable artifact that constrains the next. Machines spend within bounds established upstream—no per-transaction approval required. + +``` +PolicyGrant +↓ +SignedBudgetAuthorization +↓ +SignedPaymentAuthorization +↓ +SettlementIntent +↓ +Settlement +``` + +In fleet deployments, an optional FleetPolicyAuthorization (FPA) layer may sit above PolicyGrant. + +``` +Fleet Policy +↓ +PolicyGrant +↓ +SignedBudgetAuthorization +↓ +SignedPaymentAuthorization +↓ +SettlementIntent +↓ +Settlement +``` + +## What Each Step Does + +| Step | Artifact | Purpose | +|------|-----------|---------| +| **Fleet Policy** | Policy definition | Rules: rails, assets, vendors, caps | +| **PolicyGrant** | Session entry | "This machine may initiate payment under these constraints" | +| **SignedBudgetAuthorization** | Spending envelope | "Up to X, on these rails, to these destinations" | +| **SignedPaymentAuthorization** | Payment binding | "This exact payment was authorized" | +| **SettlementIntent** | Canonical description | Deterministic settlement parameters (optional hash binding) | +| **Settlement** | Executed transaction | Rail executes payment; verifier checks chain | + +## Key Idea + +Approval moves **upstream**. The human or policy administrator grants a **session** and **budget**. The machine spends within that budget using pre-authorized intents. Settlement becomes a background operation. + +## See Also + +- [System Model](system-model.md) — How the chain fits in the overall architecture +- [Artifact Lifecycle](artifact-lifecycle.md) — When each artifact is created +- [Reference Flow](reference-flow.md) — Full EV charging walkthrough +- [Protocol: Artifacts](protocol/artifacts.md) — Detailed artifact specs diff --git a/docs/architecture/reference-flow.md b/docs/architecture/reference-flow.md new file mode 100644 index 00000000..af145297 --- /dev/null +++ b/docs/architecture/reference-flow.md @@ -0,0 +1,1077 @@ +# Fleet EV Charging — MPCP Reference Flow + +This document describes a **complete end‑to‑end reference scenario** for using the Machine Payment Control Protocol (MPCP) in an autonomous EV fleet charging environment. + +**Chain overview:** [Authorization Chain](authorization-chain.md) — the canonical visual diagram. + +The goal is to illustrate: + +- who the actors are +- which MPCP artifacts are issued +- when each artifact is created +- where artifacts are stored +- how verification occurs +- how settlement is executed + +This scenario is intended as a **reference implementation narrative** for developers, integrators, and auditors. + +--- + +# Actors + +See: [Actors](actors.md) for a standalone overview. + +## Fleet Operator + +The fleet operator owns and manages the autonomous EV fleet. + +Responsibilities: + +- defines vehicle payment policies +- sets spending limits +- restricts allowed vendors and locations +- issues PolicyGrant artifacts + +Examples: + +- robotaxi fleet +- delivery fleet +- autonomous logistics fleet + +In this reference flow, the fleet operator is identified by an **XRPL DID** and issues fleet charging policy credentials signed under that DID. + +## Identity & Credential Layer + +This scenario assumes an optional **identity and credential layer** based on: + +- XRPL DID +- Verifiable Credentials (VCs) + +In this model: + +- the fleet operator has a DID +- the charging network operator has a DID +- the vehicle wallet may have its own DID +- selected MPCP policy artifacts may be issued as VCs + +MPCP remains the **runtime payment authorization protocol**. + +DIDs and VCs provide: + +- issuer identity +- public key discovery +- portable trust metadata +- credential verification across organizations + +They do **not** replace MPCP artifacts such as `SignedBudgetAuthorization`, `SignedPaymentAuthorization`, or `SettlementIntent`. + +## Vehicle Wallet + +Each EV contains a **machine wallet** responsible for: + +- enforcing MPCP policy constraints +- managing charging budgets +- issuing payment authorization artifacts +- executing settlement transactions + +The wallet is the MPCP actor that signs: + +- SignedBudgetAuthorization (SBA) +- SignedPaymentAuthorization (SPA) + +--- + +## Route / Dispatch System + +The dispatch system determines the route and charging requirements. + +Responsibilities: + +- determine charging locations along route +- identify approved charging networks +- provide trip metadata to the vehicle + +This system may influence the **PolicyGrant** constraints. + +--- + +## Charging Network Operator + +The charging network operator manages a network of EV charging stations. + +Responsibilities: + +- provide price quotes +- specify settlement destination +- verify MPCP authorization artifacts +- allow or deny charging sessions + +In this reference flow, the charging network operator may also publish an **XRPL DID** and issue verifiable credentials describing approved station identity, operator identity, and payment endpoints. + +--- + +## Charging Station + +The physical charger interacting with the EV. + +Responsibilities: + +- request payment authorization +- verify MPCP artifact chain +- begin charging once verification passes + +--- + +## Settlement Rail + +The settlement layer executes the payment. + +Examples: + +- XRPL + RLUSD +- stablecoin rails +- blockchain settlement systems +- traditional payment networks + +MPCP does not replace settlement systems. + +It **controls authorization above them**. + +--- + +## MPCP Verifier + +The verifier checks the full authorization chain. + +Verification may occur: + +- inside the charging operator backend +- inside a dedicated MPCP verification service +- during post‑transaction auditing + +--- + +# Fleet Charging Policy + +Before vehicles begin operating, the fleet operator defines a charging policy. + +Example constraints: + +``` +Allowed vendors: + ChargeNet + FastVolt + +Allowed geography: + Stations along active route + +Allowed settlement rail: + XRPL + +Allowed asset: + RLUSD + +Daily charging limit: + $80 + +Maximum single session: + $25 + +Allowed charging hours: + 06:00–23:00 UTC +``` + +This policy is translated into a **PolicyGrant** artifact. + +In this DID/VC-enabled version of the flow, the PolicyGrant is issued as an MPCP-native policy artifact that may also be wrapped or represented as a **Verifiable Credential**. + +This allows the EV wallet and charging infrastructure to verify: + +- who issued the policy +- which public key is authoritative +- whether the credential is still valid + +--- + +# MPCP Artifacts Used in This Scenario + +The EV charging flow uses the following MPCP artifacts. + +| Artifact | Issued By | Purpose | +|--------|--------|--------| +| PolicyGrant | Fleet policy service | Defines global payment constraints | +| PolicyGrant VC (optional) | Fleet policy service | Encodes issuer identity and verifiable policy metadata | +| SignedBudgetAuthorization | Vehicle wallet | Defines session‑level spending limits | +| SignedPaymentAuthorization | Vehicle wallet | Authorizes a specific payment | +| SettlementIntent | Vehicle wallet | Defines settlement parameters | +| Settlement Result | Settlement rail | Confirms payment execution | + + +These artifacts form the **authorization chain**. + +--- + +# High‑Level Sequence Diagram + +The following diagram summarizes the **runtime interaction flow** between the EV, charging station, and settlement rail. + +``` +Fleet Policy Service + │ + │ 1. Issue PolicyGrant (signed) + ▼ +Vehicle Wallet + │ + │ 2. Store PolicyGrant + │ + │ 3. Request quote + ▼ +Charging Station + │ + │ 4. Provide charging quote + ▼ +Vehicle Wallet + │ + │ 5. Validate policy + │ 6. Create SignedBudgetAuthorization + │ 7. Create SettlementIntent + │ 8. Create SignedPaymentAuthorization + ▼ +Charging Station / Operator Backend + │ + │ 9. Verify MPCP artifact chain + │ + │ - resolve issuer DID + │ - verify PolicyGrant + │ - verify SignedBudgetAuthorization + │ - verify SPA + │ + ▼ +Charging Station + │ + │ 10. Begin charging session + ▼ +Settlement Rail + │ + │ 11. Execute payment + ▼ +Charging Operator Backend + │ + │ 12. Store audit bundle +``` + +This diagram highlights the **separation of roles**: + +- fleet policy authority +- vehicle runtime authorization +- charging infrastructure verification +- settlement execution + +--- + +# Artifact Storage Matrix + +The following table summarizes **where each artifact typically resides**. + +| Artifact | Fleet Backend | Vehicle Wallet | Charging Operator | Settlement Rail | +|---|---|---|---|---| +| PolicyGrant | Authoritative copy | Operational copy | Optional reference | — | +| PolicyGrant VC | Optional | Optional | Optional | — | +| SignedBudgetAuthorization | Optional audit | Active session artifact | Received during authorization | — | +| SignedPaymentAuthorization | Optional audit | Created and signed | Received and verified | — | +| SettlementIntent | Optional audit | Runtime artifact | Optional (for verification) | — | +| Settlement Result | Reconciliation | Stored receipt | Stored receipt | Authoritative record | + +This matrix helps implementers understand **where artifacts should be persisted and where they are transient**. + +--- + +# Artifact Lifecycle + +## PolicyGrant + +Issued by: + +``` +Fleet Policy Service (identified by XRPL DID) +``` + +Contains: + +- allowed rails +- allowed assets +- vendor restrictions +- expiration time +- policy hash + +Stored by: + +- fleet backend +- vehicle wallet +- audit systems + +The PolicyGrant is typically issued: + +``` +Before vehicle deployment +or +Before a trip session +``` + +### PolicyGrant Storage and Signature Model + +A PolicyGrant is a **signed JSON authorization artifact** issued by the fleet operator's policy service. + +It is **not an NFT and does not require a blockchain token**. MPCP treats the PolicyGrant as a verifiable authorization credential that can be validated using the fleet operator's public key. + +In this reference flow, the fleet operator is identified by an **XRPL DID**. + +Example issuer: + +``` +issuer: did:xrpl:rFleetOperator... +issuerKeyId: did:xrpl:rFleetOperator...#key-1 +``` + +The EV wallet resolves the fleet DID to obtain the current public verification key. + +Verification model: + +``` +resolve DID +↓ +get issuer public key +↓ +verify signature on PolicyGrant +``` + +This allows the EV wallet to confirm that the policy was issued by an authorized fleet authority. + +Example structure: + +``` +{ + "artifact": "PolicyGrant", + "version": "1.0", + "grantId": "pg-983745", + "issuer": "did:xrpl:rFleetOperator...", + "issuerKeyId": "did:xrpl:rFleetOperator...#key-1", + "allowedRails": ["xrpl"], + "allowedAssets": [ + { "kind": "IOU", "currency": "RLUSD", "issuer": "rIssuer" } + ], + "vendorAllowlist": ["ChargeNet","FastVolt"], + "capPerSessionMinor": "2500", + "capPerDayMinor": "8000", + "expiresAt": "2026-03-13T23:59:00Z", + "policyHash": "abc123...", + "signature": "ed25519:..." +} +``` + +A VC representation may also be used for issuer portability. + +Example conceptual VC envelope: + +``` +{ + "@context": ["https://www.w3.org/2018/credentials/v1"], + "type": ["VerifiableCredential", "MPCPPolicyGrant"], + "issuer": "did:xrpl:rFleetOperator...", + "issuanceDate": "2026-03-12T00:00:00Z", + "expirationDate": "2026-03-13T23:59:00Z", + "credentialSubject": { + "vehicleId": "EV-847", + "policyHash": "abc123...", + "allowedRails": ["xrpl"], + "vendorAllowlist": ["ChargeNet","FastVolt"], + "capPerSessionMinor": "2500" + }, + "proof": { + "type": "Ed25519Signature2020", + "verificationMethod": "did:xrpl:rFleetOperator...#key-1", + "signature": "..." + } +} +``` + +In this model, the **MPCP artifact remains canonical**, while the VC representation provides an optional identity and trust envelope. + +### Where the PolicyGrant Lives + +In a typical deployment the PolicyGrant exists in **three locations**: + +1. **Fleet Backend (authoritative copy)** + Stored in the fleet operator's policy service database for auditing, policy management, and revocation tracking. + +2. **Vehicle Wallet (operational copy)** + Stored locally in the EV wallet so the vehicle can enforce payment constraints while offline. + +3. **Payment Authorization Bundle (optional)** + During charging authorization the EV may transmit either: + - the full PolicyGrant, or + - the `policyHash` reference + + allowing the charging operator to verify that the payment authorization follows the fleet policy. + +If a VC form is used, the vehicle may store both: + +- the canonical MPCP `PolicyGrant` +- the VC envelope containing issuer DID metadata + +The runtime authorization logic should continue to use the MPCP-native artifact fields. + +Example vehicle wallet storage model: + +``` +EV Wallet + ├─ keys + ├─ budgets + ├─ paymentAuthorizations + └─ policyGrants + └─ grantId + policyHash + expiresAt + issuer + signature +``` + +The PolicyGrant can be stored in a lightweight embedded database such as: + +- SQLite +- LevelDB +- secure key-value store +- encrypted filesystem + +### Optional Ledger Anchoring + +Some deployments may choose to anchor the `policyHash` on a public ledger for audit purposes. + +Examples: + +- XRPL memo +- Hedera Consensus Service +- Ethereum event log + +Only the **hash of the policy** would be anchored, not the full artifact. + +This provides: + +- timestamped audit proofs +- dispute resolution evidence +- tamper-detection guarantees + +However, anchoring is **optional** and not required for MPCP operation. + +--- + +## SignedBudgetAuthorization + +Issued by: + +``` +Vehicle Wallet +``` + +Purpose: + +Define the maximum spend allowed for a session and bind that budget to permitted payment rails, assets, and destinations. + +Example: + +``` +sessionId: charging-session-847 +maxAmountMinor: 2500 +currency: USD +allowedDestination: + ChargeNet +expiresAt: session end +``` + +Stored by: + +- vehicle wallet +- charging session bundle +- fleet audit system + +--- + +## SettlementIntent + +Issued by: + +``` +Vehicle Wallet +``` + +Created after the charging station provides a quote. + +Contains: + +- rail +- asset +- destination +- amount +- optional connector metadata + +SettlementIntent may produce an **intentHash** used in the SPA. + +The SettlementIntent remains an MPCP-native runtime artifact and is **not typically modeled as a Verifiable Credential**, because it is ephemeral and optimized for deterministic hashing and lightweight transport. + +--- + +## SignedPaymentAuthorization (SPA) + +Issued by: + +``` +Vehicle Wallet +``` + +Purpose: + +Authorize a specific payment request. + +Contains: + +- session reference +- settlement parameters +- optional intentHash +- decision ID +- signature + +Stored by: + +- vehicle wallet +- charging network backend +- audit logs + +The SPA is also an MPCP-native runtime artifact and is usually verified directly against the vehicle wallet's signing key rather than wrapped as a VC. + +--- + +## Settlement Result + +Issued by: + +``` +Settlement Rail +``` + +Examples: + +- XRPL transaction +- stablecoin transfer +- payment processor receipt + +Contains: + +- transaction reference +- amount +- destination +- timestamp + +--- + +# End‑to‑End Charging Timeline + +## T‑24h — Fleet Policy Definition + +Fleet operator defines charging policy. + +The policy is converted into a **PolicyGrant**. + +PolicyGrant is distributed to vehicles. + +--- + +## T‑5m — Trip Session Begins + +Vehicle receives: + +- active route +- approved charging stations +- remaining daily charging budget + +Vehicle prepares to issue a **SignedBudgetAuthorization** if needed. + +--- + +## T0 — Vehicle Arrives at Charging Station + +The EV connects to the charger. + +Charging station sends a **payment quote**. + +Example: + +``` +Charging estimate: $7.80 +Destination: ChargeNet operator account +Quote expiry: 5 minutes +``` + +--- + +## T+10s — Vehicle Policy Validation + +Vehicle checks: + +- station operator is allowed vendor +- destination is allowed +- settlement rail is allowed +- asset is allowed +- amount fits session budget +- amount fits daily limit +- fleet issuer DID resolves correctly +- policy credential signature verifies successfully + +--- + +## T+15s — Budget Authorization + +Vehicle creates or loads an active **SignedBudgetAuthorization**. + +Example: + +``` +maxAmount: $25 +session: charging-session-847 +``` + +--- + +## T+20s — Settlement Intent + +Vehicle constructs a **SettlementIntent**: + +``` +rail: XRPL +asset: RLUSD +amount: 7.80 +destination: ChargeNet account +``` + +An **intentHash** may be generated. + +--- + +## T+22s — Payment Authorization + +Vehicle signs a **SignedPaymentAuthorization**. + +This authorization binds: + +- session ID +- settlement parameters +- optional intent hash + +--- + +## T+25s — Authorization Sent to Charger + +The charger receives: + +- SignedPaymentAuthorization +- SignedBudgetAuthorization +- PolicyGrant (or reference) +- SettlementIntent (optional) + +--- + +## T+27s — Charger Verification + +Charging network verifies: + +1. fleet issuer DID resolves correctly +2. PolicyGrant or PolicyGrant VC is valid +3. SignedBudgetAuthorization is valid +4. SPA signature is valid +5. SPA parameters match the quote +6. settlement parameters match allowed policy + +If verification passes: + +``` +Charging session begins +``` + +--- + +## T+N minutes — Charging Session + +Energy delivery occurs. + +Payment may be: + +- pre‑authorized +- settled immediately +- settled at session end + +--- + +## T+Session End — Settlement + +Settlement occurs. + +Example: + +``` +XRPL payment +vehicle_wallet → ChargeNet account +``` + +Settlement result is stored. + +--- + +# Data Storage Model + +## Fleet Backend Stores + +- fleet charging policies +- PolicyGrant history +- SignedBudgetAuthorization records +- vehicle charging audit logs +- reconciliation records + +--- + +## Vehicle Wallet Stores + +- active PolicyGrant +- active SignedBudgetAuthorization +- SettlementIntent +- SignedPaymentAuthorization +- settlement receipts + +--- + +## Charging Operator Stores + +- payment quote +- MPCP artifact bundle +- optional PolicyGrant VC / issuer DID metadata +- verification results +- settlement reference +- charging session logs + +--- + +# Verification Points + +Verification happens in several places. + +## Trust Model and DID Resolution + +When XRPL DID integration is used, MPCP verification includes **issuer identity validation**. + +Typical resolution process: + +``` +PolicyGrant issuer DID + ↓ +DID resolver + ↓ +XRPL DID document + ↓ +public verification keys +``` + +The verifier then confirms: + +- the DID document is valid +- the referenced verification key exists +- the PolicyGrant signature matches that key + +This allows the charging operator to confirm that: + +- the fleet operator actually issued the policy +- the authorization chain originates from a trusted authority + +If DID resolution fails, the charging operator should treat the PolicyGrant as **untrusted** and reject the authorization. + +## Vehicle Verification + +Before authorizing payment: + +- vendor allowed +- station allowed +- destination allowed +- budget sufficient +- quote valid + +--- + +## Charging Operator Verification + +Before charging begins: + +- issuer DID resolves and credential proof is valid +- PolicyGrant valid +- SignedBudgetAuthorization valid +- SPA signature valid +- payment parameters match quote +- authorization not expired + +--- + +## Fleet Reconciliation Verification + +After settlement: + +- settlement matches authorization +- station vendor allowed +- policy constraints respected +- budgets not exceeded + +--- + +# Failure Scenarios + +## Vendor Not Allowed + +Vehicle refuses to authorize payment. + +--- + +## Quote Exceeds Budget + +Vehicle rejects charging request. + +--- + +## Destination Mismatch + +Charging operator rejects authorization. + +--- + +## Settlement Mismatch + +Verifier flags payment as invalid. + +--- + +# Audit Bundle + +For audit or dispute resolution, the following bundle may be stored: + +- PolicyGrant +- optional PolicyGrant VC +- issuer DID metadata or resolution record +- SignedBudgetAuthorization +- SignedPaymentAuthorization +- SettlementIntent +- charging quote metadata +- settlement receipt +- optional intent anchor + +This bundle allows full replay of the authorization chain. + +--- + +# Full Artifact Bundle Example + +The following example shows the kind of **self-contained authorization bundle** a charging operator could receive and store for verification, audit, or dispute replay. + +This example is intentionally simplified, but it illustrates how the full MPCP chain may be packaged. + +> Note: The example below uses display-friendly amounts (e.g., "7.80") for readability. +> Real MPCP artifacts typically encode amounts in atomic units. + +```json +{ + "bundleType": "MPCPChargingAuthorizationBundle", + "version": "1.0", + + "issuerDid": "did:xrpl:rFleetOperator...", + "vehicleDid": "did:xrpl:rVehicleWallet...", + "chargingOperatorDid": "did:xrpl:rChargeNet...", + + "policyGrant": { + "artifact": "PolicyGrant", + "version": "1.0", + "grantId": "pg-983745", + "issuer": "did:xrpl:rFleetOperator...", + "issuerKeyId": "did:xrpl:rFleetOperator...#key-1", + "allowedRails": ["xrpl"], + "allowedAssets": [ + { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer" + } + ], + "vendorAllowlist": ["ChargeNet", "FastVolt"], + "capPerSessionMinor": "2500", + "capPerDayMinor": "8000", + "expiresAt": "2026-03-13T23:59:00Z", + "policyHash": "abc123...", + "signature": "ed25519:..." + }, + + "policyGrantVc": { + "@context": ["https://www.w3.org/2018/credentials/v1"], + "type": ["VerifiableCredential", "MPCPPolicyGrant"], + "issuer": "did:xrpl:rFleetOperator...", + "issuanceDate": "2026-03-12T00:00:00Z", + "expirationDate": "2026-03-13T23:59:00Z", + "credentialSubject": { + "vehicleId": "EV-847", + "policyHash": "abc123...", + "allowedRails": ["xrpl"], + "vendorAllowlist": ["ChargeNet", "FastVolt"], + "capPerSessionMinor": "2500" + }, + "proof": { + "type": "Ed25519Signature2020", + "verificationMethod": "did:xrpl:rFleetOperator...#key-1", + "signature": "..." + } + }, + + "signedBudgetAuthorization": { + "artifact": "SignedBudgetAuthorization", + "issuer": "did:xrpl:rVehicleWallet...", + "issuerKeyId": "did:xrpl:rVehicleWallet...#key-1", + "version": "1.0", + "sessionId": "charging-session-847", + "vehicleId": "EV-847", + "policyHash": "abc123...", + "currency": "USD", + "maxAmountMinor": "2500", + "allowedRails": ["xrpl"], + "allowedAssets": [ + { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer" + } + ], + "destinationAllowlist": ["rChargeNetDestination"], + "expiresAt": "2026-03-12T15:00:00Z", + "signature": "ed25519:..." + }, + + "chargingQuote": { + "quoteId": "quote-4421", + "stationId": "station-17", + "operator": "ChargeNet", + "connectorId": "DC-FAST-2", + "destination": "rChargeNetDestination", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer" + }, + "priceFiat": { + "amountMinor": "780", + "currency": "USD" + }, + "expiresAt": "2026-03-12T14:35:00Z" + }, + + "settlementIntent": { + "artifact": "SettlementIntent", + "version": "1.0", + "rail": "xrpl", + "amount": "7.80", + "destination": "rChargeNetDestination", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer" + }, + "createdAt": "2026-03-12T14:30:20Z" + }, + + "signedPaymentAuthorization": { + "artifact": "SignedPaymentAuthorization", + "issuer": "did:xrpl:rVehicleWallet...", + "issuerKeyId": "did:xrpl:rVehicleWallet...#key-1", + "version": "1.0", + "sessionId": "charging-session-847", + "decisionId": "dec-9001", + "intentHash": "intenthash123...", + "settlement": { + "rail": "xrpl", + "destination": "rChargeNetDestination", + "amount": "7.80", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer" + } + }, + "signature": "ed25519:..." + }, + + "settlementResult": { + "rail": "xrpl", + "txHash": "ABCDEF123456...", + "amount": "7.80", + "destination": "rChargeNetDestination", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer" + }, + "nowISO": "2026-03-12T14:31:10Z" + }, + + "intentAnchor": { + "rail": "hedera-hcs", + "topicId": "0.0.123456", + "sequenceNumber": "88", + "intentHash": "intenthash123...", + "anchoredAt": "2026-03-12T14:30:25Z" + }, + + "verificationMaterial": { + "fleetDidResolution": { + "did": "did:xrpl:rFleetOperator...", + "resolvedAt": "2026-03-12T14:30:21Z", + "verificationMethod": "did:xrpl:rFleetOperator...#key-1" + }, + "chargingOperatorDidResolution": { + "did": "did:xrpl:rChargeNet...", + "resolvedAt": "2026-03-12T14:30:23Z", + "verificationMethod": "did:xrpl:rChargeNet...#key-1" + }, + "vehicleDidResolution": { + "did": "did:xrpl:rVehicleWallet...", + "resolvedAt": "2026-03-12T14:30:22Z", + "verificationMethod": "did:xrpl:rVehicleWallet...#key-1" + } + } +} +``` + +## Notes on the Example Bundle + +This bundle illustrates several important modeling choices: + +- the **canonical MPCP artifacts** remain the primary runtime objects +- the `policyGrantVc` is optional and exists to carry issuer identity and trust metadata +- DID resolution metadata for the fleet issuer, vehicle wallet, and charging operator may be stored alongside the bundle to support later audit or dispute replay +- the `chargingQuote` is not itself an MPCP artifact, but it is operationally important because the charging operator must verify that the SPA matches the quote +- the `intentAnchor` is optional and provides additional auditability without changing the core MPCP authorization chain + +In a production deployment, the exact bundle shape may vary, but it should preserve the same key property: + +**a verifier must be able to reconstruct and validate the full authorization chain from policy issuance to settlement.** + +# Summary + +This scenario demonstrates how MPCP enables **safe autonomous charging payments**. + +In this version of the flow, MPCP authorization can be anchored in a portable trust model using **XRPL DID** and optional **Verifiable Credentials**, while keeping runtime payment control artifacts lightweight and MPCP-native. + +Infrastructure can answer the critical question: + +``` +Was this vehicle actually allowed to make this payment? +``` + +MPCP provides the cryptographic proof required to answer that question. diff --git a/docs/architecture/system-model.md b/docs/architecture/system-model.md new file mode 100644 index 00000000..48598fc7 --- /dev/null +++ b/docs/architecture/system-model.md @@ -0,0 +1,42 @@ +# System Model + +MPCP models machine payments as a **cryptographic authorization chain** that sits above settlement rails. + +## Overview + +The system model has three layers: + +| Layer | Role | Examples | +|-------|------|----------| +| **Policy** | Defines spending rules | Fleet operator policy, vendor allowlists, caps | +| **Authorization** | Bounds runtime spending | PolicyGrant, SBA, SPA | +| **Settlement** | Executes payment | XRPL, EVM, Stripe, hosted | + +MPCP operates in the **authorization** layer. It does not replace or implement the settlement layer—it constrains what may be settled. + +The canonical flow is: **Fleet Policy → PolicyGrant → SBA → SPA → SettlementIntent → Settlement**. + +→ [Authorization Chain (visual diagram)](authorization-chain.md) + +## Trust Model + +- **Policy issuer** — Authority that defines rules (fleet operator, service operator) +- **Machine wallet** — Signs budgets and payment authorizations within policy +- **Verifier** — Validates the chain before allowing service or settlement +- **Settlement rail** — Executes the actual payment + +Each step produces verifiable artifacts. The verifier can independently validate the full chain without trusting any single party. + +## Key Properties + +1. **Decoupled** — Policy, budget, and payment binding are separate concerns +2. **Verifiable** — Settlement can be checked against authorization chain +3. **Offline-capable** — Machine holds chain onboard; verifier validates locally +4. **Rail-agnostic** — Same authorization model for any settlement backend + +## See Also + +- [Authorization Chain](authorization-chain.md) — The canonical visual diagram +- [Actors](actors.md) +- [Artifact Lifecycle](artifact-lifecycle.md) +- [Reference Flow](reference-flow.md) diff --git a/docs/guides/build-a-machine-wallet.md b/docs/guides/build-a-machine-wallet.md index 9a7f019a..cd2e3e0a 100644 --- a/docs/guides/build-a-machine-wallet.md +++ b/docs/guides/build-a-machine-wallet.md @@ -129,5 +129,5 @@ npm run example:guardrails ## See Also - [Examples: Parking](../examples/parking.md) -- [Protocol: Artifacts](../protocol/artifacts.md) +- [Protocol: Artifacts](protocol/artifacts.md) - [Reference: SDK](../reference/sdk.md) diff --git a/docs/guides/dispute-resolution.md b/docs/guides/dispute-resolution.md index 2803d424..ac0f844a 100644 --- a/docs/guides/dispute-resolution.md +++ b/docs/guides/dispute-resolution.md @@ -68,7 +68,7 @@ const anchor = await anchorIntent(intentHash, { rail: "hedera-hcs" }); ## See Also -- [Protocol: Anchoring](../protocol/anchoring.md) +- [Protocol: Anchoring](protocol/anchoring.md) - [Intent Anchoring](../doc/architecture/INTENT_ANCHORING.md) - [Dispute Verification](../doc/architecture/DISPUTE_VERIFICATION.md) - [Reference: Service API](../reference/service-api.md) diff --git a/docs/implementation/conformance.md b/docs/implementation/conformance.md new file mode 100644 index 00000000..ac783dc4 --- /dev/null +++ b/docs/implementation/conformance.md @@ -0,0 +1,45 @@ +# Conformance + +MPCP implementations can be verified for conformance to the protocol specification. + +## Conformance Levels + +| Level | Scope | Description | +|-------|-------|-------------| +| **Artifact** | Single artifact | Produces valid PolicyGrant, SBA, SPA, SettlementIntent per spec | +| **Chain** | Full authorization chain | Links artifacts correctly (policyHash, sessionId, constraints) | +| **Verification** | Settlement verification | Passes all verification checks for valid bundles | +| **Profile** | Deployment profile | Matches a reference profile (parking, charging, fleet-offline, hosted-rail) | + +## Verification Vectors + +The reference implementation includes golden vectors in `vectors/` for conformance testing: + +- `valid-settlement.json` — Full valid chain, must pass +- `expired-grant.json` — Expired PolicyGrant, must fail +- `budget-exceeded.json` — Amount exceeds budget, must fail +- `intent-hash-mismatch.json` — Intent hash mismatch, must fail +- `settlement-mismatch.json` — Settlement does not match SPA, must fail + +Run the conformance tests: + +```bash +npm test +npx mpcp verify vectors/valid-settlement.json --explain +``` + +## Self-Assessment + +Implementers should verify: + +1. **Artifact structure** — All required fields present, types correct +2. **Canonical JSON** — Deterministic serialization for hashing +3. **Domain-separated hashing** — Correct prefix per artifact type +4. **Signature verification** — Valid key resolution and signature check +5. **Constraint propagation** — SBA ⊆ PolicyGrant, SPA ⊆ SBA + +## See Also + +- [MPCP Reference Flow](../architecture/reference-flow.md) — Canonical flow for EV charging +- [Verifier](verifier.md) — Verification pipeline +- [Protocol: mpcp](protocol/mpcp.md) — Full specification diff --git a/docs/implementation/sdk.md b/docs/implementation/sdk.md new file mode 100644 index 00000000..31837781 --- /dev/null +++ b/docs/implementation/sdk.md @@ -0,0 +1,143 @@ +# SDK Reference + +The MPCP SDK provides lower-level artifact creation, hashing, and verification. + +## Install + +```bash +npm install mpcp-service +``` + +## Import + +```typescript +import { + createPolicyGrant, + createBudgetAuthorization, + createSignedBudgetAuthorization, + createSignedPaymentAuthorization, + createSettlementIntent, + computeSettlementIntentHash, + computeIntentHash, + canonicalJson, + verifyPolicyGrant, + verifySettlement, + verifySettlementWithReport, + verifySettlementDetailed, +} from "mpcp-service/sdk"; +``` + +## Policy Grant + +```typescript +import { createPolicyGrant } from "mpcp-service/sdk"; + +const grant = createPolicyGrant({ + policyHash: "a1b2c3", + allowedRails: ["xrpl", "evm"], + allowedAssets: [{ kind: "IOU", currency: "RLUSD", issuer: "rIssuer" }], + expiresAt: "2030-12-31T23:59:59Z", +}); +``` + +## Budget Authorization + +```typescript +import { + createBudgetAuthorization, + createSignedBudgetAuthorization, +} from "mpcp-service/sdk"; + +const budgetAuth = createBudgetAuthorization({ + sessionId: "sess-123", + vehicleId: "veh-456", + policyHash: "a1b2c3", + currency: "USD", + maxAmountMinor: "3000", + allowedRails: ["xrpl"], + allowedAssets: [{ kind: "IOU", currency: "RLUSD", issuer: "rIssuer" }], + destinationAllowlist: ["rParking"], + expiresAt: "2030-12-31T23:59:59Z", +}); + +// Signed (requires MPCP_SBA_SIGNING_PRIVATE_KEY_PEM) +const sba = createSignedBudgetAuthorization({ + sessionId: budgetAuth.sessionId, + vehicleId: budgetAuth.vehicleId, + policyHash: budgetAuth.policyHash, + currency: budgetAuth.currency, + maxAmountMinor: budgetAuth.maxAmountMinor, + allowedRails: budgetAuth.allowedRails, + allowedAssets: budgetAuth.allowedAssets, + destinationAllowlist: budgetAuth.destinationAllowlist, + expiresAt: budgetAuth.expiresAt, +}); +``` + +## Payment Authorization + +```typescript +import { + createSignedPaymentAuthorization, + createSettlementIntent, + computeSettlementIntentHash, +} from "mpcp-service/sdk"; + +const intent = createSettlementIntent({ + rail: "xrpl", + amount: "1000", + destination: "rParking", + asset: { kind: "IOU", currency: "RLUSD", issuer: "rIssuer" }, +}); + +const spa = createSignedPaymentAuthorization({ + decisionId: "dec-789", + sessionId: "sess-123", + policyHash: "a1b2c3", + quoteId: "quote-17", + rail: "xrpl", + asset: { kind: "IOU", currency: "RLUSD", issuer: "rIssuer" }, + amount: "1000", + destination: "rParking", + intentHash: computeSettlementIntentHash(intent), + expiresAt: "2030-12-31T23:59:59Z", +}); +``` + +Requires `MPCP_SPA_SIGNING_PRIVATE_KEY_PEM`. + +## Hashing + +```typescript +import { computeSettlementIntentHash, computeIntentHash, canonicalJson } from "mpcp-service/sdk"; + +const intentHash = computeSettlementIntentHash(intent); +const canonical = canonicalJson({ rail: "xrpl", amount: "1000", destination: "rDest" }); +``` + +## Verification + +```typescript +import { verifySettlement, verifySettlementWithReport, verifySettlementDetailed } from "mpcp-service/sdk"; + +const result = verifySettlement(context); +const { result, steps } = verifySettlementWithReport(context); +const { valid, checks } = verifySettlementDetailed(context); +``` + +## Environment Variables + +| Variable | Purpose | +|----------|---------| +| MPCP_SBA_SIGNING_PRIVATE_KEY_PEM | Private key for signing SBAs | +| MPCP_SBA_SIGNING_PUBLIC_KEY_PEM | Public key for verifying SBAs | +| MPCP_SBA_SIGNING_KEY_ID | Key identifier (default: mpcp-sba-signing-key-1) | +| MPCP_SPA_SIGNING_PRIVATE_KEY_PEM | Private key for signing SPAs | +| MPCP_SPA_SIGNING_PUBLIC_KEY_PEM | Public key for verifying SPAs | +| MPCP_SPA_SIGNING_KEY_ID | Key identifier (default: mpcp-spa-signing-key-1) | + +## See Also + +- [MPCP Reference Flow](../architecture/reference-flow.md) — End-to-end flow with SDK usage +- [Service API](../reference/service-api.md) — Higher-level facade +- [Build a Machine Wallet](../guides/build-a-machine-wallet.md) diff --git a/docs/implementation/verifier.md b/docs/implementation/verifier.md new file mode 100644 index 00000000..d82f577a --- /dev/null +++ b/docs/implementation/verifier.md @@ -0,0 +1,54 @@ +# Verifier + +MPCP settlement verification ensures that an executed transaction matches the authorization chain. + +## Verification Pipeline + +The verifier runs checks in order: + +1. **Schema** — All artifacts parse and validate against expected structure +2. **Linkage** — PolicyGrant → SBA → SPA chain is consistent (sessionId, policyHash, constraints) +3. **Hash** — If intentHash is present, it matches `computeSettlementIntentHash(settlementIntent)` +4. **Policy** — Budget limits, rail/asset/destination constraints, expiration + +If any check fails, verification fails with a specific reason. + +## What Is Verified + +| Check | Description | +|-------|-------------| +| PolicyGrant | ExpiresAt not passed; constraints valid | +| SBA | Signature valid; expiresAt not passed; sessionId, policyHash match | +| SBA → decision | Budget not exceeded; rail, asset, destination in allowlists | +| SPA | Signature valid; expiresAt not passed | +| SPA → settlement | decisionId, rail, amount, destination, asset match executed settlement | +| intentHash | If present, equals hash of settlement intent | + +## Usage + +```typescript +import { verifySettlement } from "mpcp-service"; + +const result = verifySettlement(context); + +if (result.valid) { + // Settlement matches authorization chain +} else { + // result.reason describes the failure +} +``` + +The `context` includes policyGrant, signedBudgetAuthorization, signedPaymentAuthorization, settlement, paymentPolicyDecision, decisionId, and optional settlementIntent. + +## Dispute Verification + +When a settlement is disputed, `verifyDisputedSettlement` runs full chain verification plus optional ledger anchor verification. If the intent was anchored (e.g., to Hedera HCS), the anchor can be checked against the expected intentHash. + +See [Dispute Resolution](../guides/dispute-resolution.md) for the guide. + +## See Also + +- [MPCP Reference Flow](../architecture/reference-flow.md) — End-to-end verification in EV charging +- [Protocol: Artifacts](protocol/artifacts.md) +- [Protocol: Hashing](protocol/hashing.md) +- [Reference: CLI](../reference/cli.md) — `mpcp verify` command diff --git a/docs/index.md b/docs/index.md index fa2eb1d0..42eb0bac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,13 +6,24 @@ Autonomous vehicles, AI agents, and machines increasingly pay for real-world services like parking, charging, and tolls. -MPCP provides a **cryptographically verifiable authorization chain** for these payments. +## How MPCP works + +A machine payment is accepted only if the recipient can verify a chain of signed artifacts: + +**[Fleet Policy](architecture/authorization-chain.md) → [PolicyGrant](protocol/PolicyGrant.md) → [SignedBudgetAuthorization](protocol/SignedBudgetAuthorization.md) → [SignedPaymentAuthorization](protocol/SignedPaymentAuthorization.md) → [SettlementIntent](protocol/SettlementIntent.md) → Settlement** + +Each step narrows what the machine is allowed to do. + +→ [See the full reference flow](architecture/reference-flow.md) + + +MPCP is not a settlement rail — it is the authorization layer above settlement.
- **Understand the Problem** Why existing payment APIs are not designed for autonomous machines. - → [Read the problem](overview/problem.md) + → [Read the problem](overview/problem-statement.md) - **Learn the Protocol** See the MPCP authorization chain and how it works. @@ -33,26 +44,32 @@ MPCP provides a **cryptographically verifiable authorization chain** for these p MPCP defines a sequence of artifacts that authorize and verify a machine payment. ``` +Fleet Policy +↓ PolicyGrant - ↓ -BudgetAuthorization - ↓ -PaymentAuthorization - ↓ +↓ +SignedBudgetAuthorization +↓ +SignedPaymentAuthorization +↓ +SettlementIntent +↓ Settlement ``` -1. **PolicyGrant** - Defines where a machine is allowed to pay. +1. **Fleet Policy** — Defines rules: where, when, how much a machine may spend. + +2. **PolicyGrant** — Initial permission envelope derived from policy. + +3. **SignedBudgetAuthorization (SBA)** — Session-level spending limits. + +4. **SignedPaymentAuthorization (SPA)** — Binds a specific payment to the approved quote. -2. **BudgetAuthorization** - Defines spending limits for a session. +5. **SettlementIntent** — Canonical description of the payment to execute. -3. **PaymentAuthorization** - Authorizes a specific payment. +6. **Settlement** — Executed transaction verified against the chain. -4. **Settlement** - Final transaction verification. +→ [Authorization Chain (visual reference)](architecture/authorization-chain.md) ## Where MPCP Fits in the Agent Stack @@ -69,8 +86,8 @@ MPCP complements agent protocols by enabling **verifiable payment authorization 1. A vehicle enters a parking garage. 2. The garage verifies a **PolicyGrant**. -3. The vehicle presents a **BudgetAuthorization** for the session. -4. When exiting, a **PaymentAuthorization** is issued. +3. The vehicle presents a **SignedBudgetAuthorization (SBA)** for the session. +4. When exiting, a **SignedPaymentAuthorization (SPA)** is issued. 5. The garage verifies settlement. This ensures the payment can be independently verified. @@ -94,7 +111,7 @@ MPCP allows machines, service providers, and verification systems to independent ## Specification -The full protocol specification is in the [MPCP specification](doc/protocol/mpcp.md). The [reference implementation](https://github.com/naory/mpcp-service) is available on GitHub. +The full protocol specification is in the [MPCP specification](protocol/mpcp.md). The [reference implementation](https://github.com/naory/mpcp-service) is available on GitHub. ## Start Building diff --git a/docs/overview/comparison-with-agent-protocols.md b/docs/overview/comparison-with-agent-protocols.md index dad785d3..3262929f 100644 --- a/docs/overview/comparison-with-agent-protocols.md +++ b/docs/overview/comparison-with-agent-protocols.md @@ -75,4 +75,4 @@ Consider AP2 when: - [What is MPCP?](what-is-mpcp.md) - [The Problem](problem.md) -- [Protocol: Artifacts](../protocol/artifacts.md) +- [Protocol: Artifacts](protocol/artifacts.md) diff --git a/docs/overview/design-goals.md b/docs/overview/design-goals.md new file mode 100644 index 00000000..66da0926 --- /dev/null +++ b/docs/overview/design-goals.md @@ -0,0 +1,86 @@ +# Design Goals + +MPCP is designed around explicit goals that distinguish it from traditional payment systems and other agent payment protocols. + +## Core Goals + +### 1. Bounded Authorization + +Machines must spend **within policy-defined limits**, not per transaction. Approval moves upstream: the human or policy administrator grants a session and budget; the machine spends autonomously within that envelope. + +- No per-transaction wallet popups +- No unbounded access +- Cryptographically enforced constraints + +### 2. Offline-Capable Payments + +Payments must complete when the network is unavailable. Underground parking, tunnels, remote charging facilities—connectivity cannot be assumed. + +- Pre-loaded policy chain onboard the machine +- Local verification by the service provider +- No central backend contact at payment time + +### 3. Verifiable Chain + +Every settlement must be independently verifiable against the authorization chain. PolicyGrant → SBA → SPA → Settlement forms a traceable, auditable sequence. + +- Each step produces a signed or verifiable artifact +- Operators and auditors can trace from settlement back to policy +- Deterministic verification rules + +### 4. Settlement-Agnostic Policy + +Policy and budget are expressed in abstract terms (caps, rails, destinations). Settlement details (tx hash, chain) are handled at execution and verification. + +- Works with XRPL, EVM, Stripe, hosted—any rail +- One authorization model, pluggable settlement backends +- Rail-agnostic from the start + +### 5. Separation of Concerns + +Policy evaluation is distinct from budget issuance, which is distinct from payment binding. Each layer can be audited, tested, and replaced independently. + +- Minimal disclosure: budget does not need to know every future payment +- Payment authorization binds only what is necessary for that settlement + +## Architecture Principles + +The protocol follows a deliberate pipeline: + +``` +Policy + ↓ +PolicyGrant (session entry) + ↓ +SignedBudgetAuthorization (spending envelope) + ↓ +SignedPaymentAuthorization (binding to specific settlement) + ↓ +Settlement Execution + ↓ +Settlement Verification +``` + +This sequence ensures: + +1. **Separation of concerns** — Each layer has a single responsibility +2. **Minimal disclosure** — No over-sharing of payment details +3. **Verifiable chain** — Signed artifacts at each step +4. **Settlement-agnostic policy** — Abstract constraints, concrete execution + +## Comparison with Alternatives + +| | MPCP | x402 | AP2 | +|---|------|------|-----| +| **Primary use case** | Physical machines, fleet payments, variable sessions | API access payments, pay-per-request | Agent commerce | +| **Authorization model** | Pre-authorized budgets | Per-request payment | Verifiable mandates | +| **Offline** | Yes | No | No | +| **Settlement rails** | Any | Stablecoins on supported chains | Cards, x402 | + +See [Comparison with Agent Protocols](comparison-with-agent-protocols.md) for a detailed comparison. + +## See Also + +- [What is MPCP?](what-is-mpcp.md) +- [Problem Statement](problem-statement.md) +- [Reference Flow](../architecture/reference-flow.md) — Full EV charging reference scenario diff --git a/docs/overview/problem-statement.md b/docs/overview/problem-statement.md new file mode 100644 index 00000000..1d1ae100 --- /dev/null +++ b/docs/overview/problem-statement.md @@ -0,0 +1,62 @@ +# The Problem + +Traditional payment systems assume a **human approves every transaction**. A card swipe, a bank transfer, or a wallet signature—each involves an explicit human decision at the moment of payment. + +Machine payments break that assumption. + +## Why Human-Centric Systems Fail for Machines + +### 1. Autonomous Systems Cannot Pause for Approval + +An autonomous vehicle cannot stop at a toll gate to open a wallet popup. A delivery robot cannot wait for a human to approve each charging station payment. An AI agent cannot interrupt a workflow every few seconds for manual consent. + +**Machines need to spend within bounds, not per transaction.** + +### 2. Wallet Popups Don't Scale + +In Web3 and wallet-based flows, the dominant pattern is "sign to approve." Each payment triggers a wallet interaction. This works when a human is at the keyboard. + +It does **not** work when: + +- **Volume is high** — Hundreds of micropayments per vehicle per day (parking, charging, tolls) cannot each require a popup +- **Latency matters** — A gate does not wait 30 seconds for a user to find their phone +- **The user is absent** — A robot, IoT device, or background agent has no human to click "Confirm" +- **UX matters** — Frequent popups destroy usability and adoption + +### 3. Connectivity Cannot Be Assumed + +Autonomous fleets operate where connectivity may be intermittent: + +- Underground parking garages +- Tunnels +- Charging facilities in remote areas +- Dense urban environments with unreliable links + +Traditional systems rely on centralized approval APIs. When connectivity is lost, transactions cannot complete. Machines need to **authorize and verify locally** when the network is down. + +### 4. Unbounded Access Is Unacceptable + +Without constraints, granting a machine the ability to pay is reckless. A single compromised agent could drain an account. A bug could trigger runaway spending. + +The alternative—blocking every payment on human approval—doesn't scale and defeats autonomy. + +**We need bounded authorization: machines can spend, but only within policy-defined limits.** + +## What MPCP Provides + +MPCP solves this by shifting approval **upstream**: + +1. **Policy** — Defines rules: where, when, how much, and under what conditions spending is allowed +2. **Budget (SBA)** — Authorizes a spending envelope for a session (e.g., $30 for parking today) +3. **Payment (SPA)** — Binds each specific settlement to the approved quote + +The human (or policy administrator) approves a **session** and a **budget**. The machine spends within that budget using pre-authorized intents. Settlement becomes a background operation, not an interactive one. + +When the network is unavailable, the machine holds the policy chain onboard and can sign payments locally. The verifier (e.g., parking meter) validates the chain locally. No central backend is contacted at payment time. + +## Next Steps + +- [Design Goals](design-goals.md) — How MPCP differs from x402, AP2, and others +- [Reference Flow](../architecture/reference-flow.md) — End-to-end EV charging scenario +- [Protocol: Artifacts](protocol/artifacts.md) — The authorization chain +- [Offline Payments](../guides/fleet-payments.md#offline-flow) — How pre-authorized budgets enable offline payment diff --git a/docs/overview/problem.md b/docs/overview/problem.md index e13ae268..70692b4d 100644 --- a/docs/overview/problem.md +++ b/docs/overview/problem.md @@ -1,61 +1,7 @@ # The Problem -Traditional payment systems assume a **human approves every transaction**. A card swipe, a bank transfer, or a wallet signature—each involves an explicit human decision at the moment of payment. +This page has moved. -Machine payments break that assumption. +The MPCP problem description now lives here: -## Why Human-Centric Systems Fail for Machines - -### 1. Autonomous Systems Cannot Pause for Approval - -An autonomous vehicle cannot stop at a toll gate to open a wallet popup. A delivery robot cannot wait for a human to approve each charging station payment. An AI agent cannot interrupt a workflow every few seconds for manual consent. - -**Machines need to spend within bounds, not per transaction.** - -### 2. Wallet Popups Don't Scale - -In Web3 and wallet-based flows, the dominant pattern is "sign to approve." Each payment triggers a wallet interaction. This works when a human is at the keyboard. - -It does **not** work when: - -- **Volume is high** — Hundreds of micropayments per vehicle per day (parking, charging, tolls) cannot each require a popup -- **Latency matters** — A gate does not wait 30 seconds for a user to find their phone -- **The user is absent** — A robot, IoT device, or background agent has no human to click "Confirm" -- **UX matters** — Frequent popups destroy usability and adoption - -### 3. Connectivity Cannot Be Assumed - -Autonomous fleets operate where connectivity may be intermittent: - -- Underground parking garages -- Tunnels -- Charging facilities in remote areas -- Dense urban environments with unreliable links - -Traditional systems rely on centralized approval APIs. When connectivity is lost, transactions cannot complete. Machines need to **authorize and verify locally** when the network is down. - -### 4. Unbounded Access Is Unacceptable - -Without constraints, granting a machine the ability to pay is reckless. A single compromised agent could drain an account. A bug could trigger runaway spending. - -The alternative—blocking every payment on human approval—doesn't scale and defeats autonomy. - -**We need bounded authorization: machines can spend, but only within policy-defined limits.** - -## What MPCP Provides - -MPCP solves this by shifting approval **upstream**: - -1. **Policy** — Defines rules: where, when, how much, and under what conditions spending is allowed -2. **Budget (SBA)** — Authorizes a spending envelope for a session (e.g., $30 for parking today) -3. **Payment (SPA)** — Binds each specific settlement to the approved quote - -The human (or policy administrator) approves a **session** and a **budget**. The machine spends within that budget using pre-authorized intents. Settlement becomes a background operation, not an interactive one. - -When the network is unavailable, the machine holds the policy chain onboard and can sign payments locally. The verifier (e.g., parking meter) validates the chain locally. No central backend is contacted at payment time. - -## Next Steps - -- [Comparison with Agent Protocols](comparison-with-agent-protocols.md) — How MPCP differs from x402, AP2, and others -- [Protocol: Artifacts](../protocol/artifacts.md) — The authorization chain -- [Offline Payments](../guides/fleet-payments.md#offline-flow) — How pre-authorized budgets enable offline payment +→ [Problem Statement](problem-statement.md) diff --git a/docs/overview/what-is-mpcp.md b/docs/overview/what-is-mpcp.md index 0aa071e3..89f0466a 100644 --- a/docs/overview/what-is-mpcp.md +++ b/docs/overview/what-is-mpcp.md @@ -38,6 +38,6 @@ MPCP does **not**: ## Next Steps -- [The Problem](problem.md) — Why existing payment systems fail for machines +- [Problem Statement](problem-statement.md) — Why existing payment systems fail for machines - [Comparison with Agent Protocols](comparison-with-agent-protocols.md) — How MPCP differs from x402, AP2, and others -- [Protocol: Artifacts](../protocol/artifacts.md) — The authorization chain in detail +- [Protocol: Artifacts](protocol/artifacts.md) — The authorization chain in detail diff --git a/docs/protocol/FleetPolicyAuthorization.md b/docs/protocol/FleetPolicyAuthorization.md new file mode 100644 index 00000000..4c10b250 --- /dev/null +++ b/docs/protocol/FleetPolicyAuthorization.md @@ -0,0 +1,307 @@ +# Fleet Policy Authorization (FPA) + +Artifact Type: MPCP:FPA + +Part of the [Machine Payment Control Protocol (MPCP)](./mpcp.md). + +--- + +# 1. Purpose + +Fleet Policy Authorization (FPA) introduces **fleet‑side policy authority** into MPCP. + +While MPCP already defines operator-issued controls such as: + +- PolicyGrant +- SignedBudgetAuthorization (SBA) +- SignedPaymentAuthorization (SPA) + +large autonomous fleets require **their own governance layer** over machine payments. + +Examples: + +- robotaxi fleets (Waymo, Tesla, Uber AV) +- delivery fleets +- logistics robots +- autonomous trucking + +Fleet operators must ensure that vehicles only spend funds **within fleet‑defined risk and compliance boundaries**. + +FPA enables this capability by allowing fleets to issue **signed policy artifacts** that constrain all MPCP spending decisions. + +--- + +# 2. Problem Statement + +Without fleet authority, payment policy is controlled solely by service operators: + +``` +Operator Policy + ↓ +PolicyGrant + ↓ +SBA + ↓ +SPA + ↓ +Settlement +``` + +This model is insufficient for enterprise fleets because: + +- fleets must enforce **spending limits** +- fleets must enforce **vendor allowlists** +- fleets must enforce **geographic restrictions** +- fleets must enforce **rail/asset restrictions** +- fleets must retain **audit control** + +FPA introduces a **fleet policy layer** that intersects with operator policy. + +--- + +# 3. Policy Intersection Model + +Under FPA, the effective payment policy is the **intersection of fleet policy and operator policy**. + +``` +Fleet Policy (FPA) + ∩ +Operator Policy (PolicyGrant) + ↓ +Effective Grant + ↓ +SBA + ↓ +SPA + ↓ +Settlement +``` + +Rules: + +- **Lowest cap wins** +- **Allowed rails intersect** +- **Allowed assets intersect** +- **Operator must be fleet-approved** +- **Geographic restrictions must satisfy both sides** + +This ensures that both the service provider and the fleet operator maintain governance. + +--- + +# 4. FleetPolicyAuthorization Artifact + +The FleetPolicyAuthorization artifact is issued and signed by the **fleet authority**. + +Example: + +```json +{ + "authorization": { + "version": "1.0", + "fleetPolicyId": "fp_123", + "fleetId": "fleet_waymo_sf", + "vehicleId": "veh_456", + "scope": "DAY", + "currency": "USD", + "minorUnit": 2, + "maxAmountMinor": "5000", + "allowedRails": ["xrpl", "stripe"], + "allowedAssets": ["RLUSD"], + "allowedOperators": ["operator_42", "operator_77"], + "geoFence": ["sf_zone_a"], + "expiresAt": "2026-03-09T23:59:59Z" + }, + "signature": "base64(signature)", + "keyId": "fleet-signing-key-1" +} +``` + +Fields: + +| Field | Description | +|------|-------------| +| version | MPCP semantic version | +| fleetPolicyId | unique identifier | +| fleetId | issuing fleet | +| vehicleId | vehicle identifier | +| scope | SESSION / DAY / SHIFT | +| currency | reference currency | +| minorUnit | decimal scale | +| maxAmountMinor | maximum spend allowed | +| allowedRails | permitted payment rails | +| allowedAssets | permitted payment assets | +| allowedOperators | service operators allowed | +| geoFence | optional geographic restrictions | +| expiresAt | expiration timestamp | + +FleetPolicyAuthorization uses the MPCP signed envelope pattern. +The signature protects the inner `authorization` payload. + +--- + +## Signature Model + +FleetPolicyAuthorization signatures use MPCP domain‑separated hashing. + +``` +hash = SHA256( + "MPCP:FPA:1.0:" || canonicalJson(authorization) +) +``` + +The fleet authority signs the hash using its signing key. + +This ensures the artifact cannot collide with other MPCP artifacts. + +--- + +# 5. Effective Policy Computation + +When an MPCP verifier processes a transaction, it computes the **effective policy**. + +Example pseudocode: + +``` +effectiveRails = intersect(FPA.allowedRails, PolicyGrant.allowedRails) + + effectiveAssets = intersect(FPA.allowedAssets, PolicyGrant.allowedAssets) + + effectiveCap = min(FPA.maxAmountMinor, PolicyGrant.maxSpend) + + operatorAllowed = PolicyGrant.operatorId in FPA.allowedOperators +``` + +If any constraint fails, the settlement must be rejected. + +--- + +# 6. Verification Rules + +The verifier must check: + +1. **FPA signature validity** +2. **FPA expiration** +3. **vehicleId consistency** +4. **operator allowlist compliance** +5. **rail compatibility** +6. **asset compatibility** +7. **spending cap compliance** + +Then proceed with standard MPCP verification: + +``` +FPA + ↓ +PolicyGrant + ↓ +SBA + ↓ +SPA + ↓ +SettlementIntent +``` + +--- + +# 7. Security Properties + +FPA introduces several important security guarantees: + +### Fleet Governance + +Fleet operators can enforce payment policy independent of vendors. + +### Delegated Autonomy + +Vehicles can autonomously pay while still operating under fleet risk limits. + +### Vendor Neutrality + +The same fleet policy can apply across: + +- parking +- charging +- tolling +- depot access +- logistics infrastructure + +### Auditability + +Fleet operators can later prove: + +- that a payment was allowed +- that it remained within fleet limits +- that operator policies were respected. + +--- + +# 8. Relationship to MPCP Artifacts + +FPA sits **above PolicyGrant** in the MPCP lineage model. + +``` +FleetPolicyAuthorization (FPA) + ↓ +PolicyGrant + ↓ +SignedBudgetAuthorization (SBA) + ↓ +SignedPaymentAuthorization (SPA) + ↓ +SettlementIntent + ↓ +Settlement +``` + +Each artifact must remain compliant with the constraints of the artifacts above it. + +--- + +# 9. Enterprise Use Cases + +### Robotaxi Fleets + +Robotaxis may only spend: + +- within a city +- at approved charging stations +- within a daily spending envelope. + +### Delivery Fleets + +Delivery robots may pay for: + +- micro‑parking +- depot access +- loading dock reservations. + +### Autonomous Trucking + +Trucks may pay for: + +- toll roads +- charging stations +- logistics hubs. + +--- + +# 10. Future Extensions + +Possible enhancements include: + +- multi‑fleet policy federation +- regional fleet authorities +- zero‑knowledge fleet policy proofs +- on‑chain policy anchors +- delegated policy keys + +--- + +# 11. Summary + +FleetPolicyAuthorization introduces **enterprise fleet governance** into MPCP. + +It allows fleets to maintain policy authority over autonomous machine payments while preserving interoperability with MPCP service providers. + +This extension enables MPCP to support **large-scale autonomous fleets and agent economies**. diff --git a/docs/protocol/PolicyGrant.md b/docs/protocol/PolicyGrant.md new file mode 100644 index 00000000..1d211494 --- /dev/null +++ b/docs/protocol/PolicyGrant.md @@ -0,0 +1,206 @@ +# PolicyGrant + +Artifact Type: MPCP:PolicyGrant + +Part of the [Machine Payment Control Protocol (MPCP)](./mpcp.md). + +--- + +## Purpose + +A **PolicyGrant** represents the result of a policy evaluation performed before a machine is allowed to initiate payment activity. + +The PolicyGrant defines the **initial permission envelope** for a session or payment scope. It constrains which rails, assets, and spending limits may later be authorized via MPCP artifacts such as: + +- **SignedBudgetAuthorization (SBA)** +- **SignedPaymentAuthorization (SPA)** + +PolicyGrant is typically produced by a policy engine during an **entry phase** when a machine, vehicle, or agent attempts to access a service. + +Unlike SBA and SPA, a PolicyGrant is usually **internal to the policy engine boundary** and may or may not be signed. + +--- + +## Problem + +In autonomous payment environments (vehicles, robots, AI agents), a system must determine **whether payment activity is allowed before any transaction is authorized**. + +Without a formal grant artifact: + +- agents may bypass policy +- payment decisions may not be traceable to policy evaluation +- downstream authorizations cannot prove they were derived from policy + +PolicyGrant solves this by creating a **verifiable policy snapshot** that later artifacts must reference. + +--- + +## Policy Lifecycle Context + +Policy evaluation typically occurs in three phases: + +``` +PolicyGrant + ↓ +SignedBudgetAuthorization (SBA) + ↓ +SignedPaymentAuthorization (SPA) + ↓ +Settlement verification +``` + +PolicyGrant establishes the **upper policy boundary** that subsequent artifacts must respect. + +For example: + +- allowed rails +- allowed assets +- spending caps +- policy expiration + +Downstream artifacts must be **subsets of the PolicyGrant constraints**. + +--- + +## Structure + +### PolicyGrant (payload) + +| Field | Type | Required | Description | +|------|------|----------|-------------| +| version | string | yes | MPCP semantic version (e.g. "1.0") | +| grantId | string | yes | Unique identifier for the grant | +| policyHash | string | yes | Hash of the evaluated policy snapshot | +| subjectId | string | yes | Identifier of the entity receiving the grant (vehicle, agent, wallet, etc.) | +| operatorId | string | optional | Service operator identifier | +| scope | string | yes | Scope of the grant (SESSION, VEHICLE, FLEET, etc.) | +| allowedRails | Rail[] | yes | Payment rails permitted by policy | +| allowedAssets | Asset[] | conditional | Allowed assets for on-chain rails | +| maxSpend | object | optional | Spending caps defined by policy | +| expiresAt | string | yes | ISO 8601 expiration timestamp | +| requireApproval | boolean | optional | Indicates that further approval is required before payment | +| reasons | string[] | optional | Policy evaluation reasons | + +--- + +## Example + +```json +{ + "version": "1.0", + "grantId": "grant_7ab3", + "policyHash": "9f3a0d...", + "subjectId": "vehicle_1284", + "operatorId": "operator_12", + "scope": "SESSION", + "allowedRails": ["xrpl", "stripe"], + "allowedAssets": [ + { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer..." + } + ], + "maxSpend": { + "perTxMinor": "5000", + "perSessionMinor": "20000" + }, + "expiresAt": "2026-03-08T14:00:00Z", + "requireApproval": false, + "reasons": ["OK"] +} +``` + +--- + +## Policy Intersection Model + +PolicyGrant may represent the intersection of multiple policy sources. + +Example policy layers: + +- operator policy +- fleet policy +- user policy +- regulatory policy + +The effective policy becomes: + +``` +effectivePolicy = + operatorPolicy + ∩ fleetPolicy + ∩ userPolicy + ∩ regulatoryPolicy +``` + +The PolicyGrant stores the **resulting effective constraints**. + +--- + +## Relationship to SBA + +A **SignedBudgetAuthorization** must always be a subset of the PolicyGrant. + +For example: + +``` +SBA.allowedRails ⊆ PolicyGrant.allowedRails +SBA.allowedAssets ⊆ PolicyGrant.allowedAssets +SBA.maxAmount ≤ PolicyGrant.maxSpend +``` + +The SBA must reference the same **policyHash** used to produce the PolicyGrant. + +--- + +## Relationship to SPA + +A **SignedPaymentAuthorization** must ultimately derive from a policy decision that was allowed by the PolicyGrant. + +Therefore: + +``` +SPA.rail ∈ PolicyGrant.allowedRails +SPA.asset ∈ PolicyGrant.allowedAssets +SPA.amount ≤ PolicyGrant.maxSpend +``` + +--- + +## Expiration + +PolicyGrant defines the **maximum validity window** for downstream artifacts. + +Implementations MUST ensure: + +- SBA expiration does not exceed PolicyGrant expiration +- SPA expiration does not exceed PolicyGrant expiration + +--- + +## Signing (Optional) + +PolicyGrant is typically an **internal artifact** and does not require cryptographic signing. + +However, MPCP implementations may optionally define a signed variant if the grant must cross trust boundaries. + +In such cases, the artifact would follow MPCP domain-separated hashing: + +``` +SHA256("MPCP:PolicyGrant::" || canonicalJson(grant)) +``` + +--- + +## Summary + +PolicyGrant establishes the **policy boundary** for machine payments. + +It ensures that downstream artifacts (SBA and SPA) are always derived from a **validated policy evaluation**. + +--- + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Demonstrates how PolicyGrant is used during runtime authorization. diff --git a/docs/protocol/SettlementIntent.md b/docs/protocol/SettlementIntent.md new file mode 100644 index 00000000..668a8e17 --- /dev/null +++ b/docs/protocol/SettlementIntent.md @@ -0,0 +1,207 @@ +# SettlementIntent + +Artifact Type: MPCP:SettlementIntent + +Part of the [Machine Payment Control Protocol (MPCP)](./mpcp.md). + +--- + +## Purpose + +A **SettlementIntent** defines the canonical description of a payment that an agent intends to execute. + +It represents the **deterministic settlement parameters** that must match the eventual payment transaction. A hash of the intent (`intentHash`) may be embedded in higher‑level artifacts such as **SignedPaymentAuthorization (SPA)**. + +SettlementIntent allows MPCP implementations to: + +- bind a payment authorization to a deterministic settlement description +- verify that a payment matches the intended parameters +- prevent parameter tampering +- enable cross‑rail verification + +SettlementIntent itself is typically **not signed**. Instead, its hash is referenced and protected by signatures of higher‑level artifacts. + +--- + +## Problem + +In autonomous payment environments, clients executing payments may attempt to alter parameters such as: + +- payment amount +- destination address +- payment rail +- asset + +If those parameters are not deterministically bound to the authorization artifact, a payment could diverge from the policy decision. + +SettlementIntent solves this by defining a **canonical payment description** whose hash can be embedded in signed artifacts. + +--- + +## Structure + +### SettlementIntent (payload) + +| Field | Type | Required | Description | +|------|------|----------|-------------| +| version | string | yes | MPCP semantic version (e.g. "1.0") | +| rail | Rail | yes | Payment rail (xrpl, evm, stripe, hosted) | +| asset | Asset | conditional | Required for on‑chain rails | +| amount | string | yes | Amount in atomic units | +| destination | string | conditional | Destination address for on‑chain rails | +| referenceId | string | optional | Identifier linking intent to decision or quote | +| createdAt | string | optional | ISO 8601 timestamp. Metadata for audit/debugging; excluded from canonical hashing unless a temporal profile explicitly requires it. | + +--- + +## Example + +```json +{ + "version": "1.0", + "rail": "xrpl", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer..." + }, + "amount": "19440000", + "destination": "rDestination...", + "referenceId": "quote_17", + "createdAt": "2026-03-08T13:55:00Z" +} +``` + +--- + +## Intent Hash + +The **intentHash** is the deterministic identifier derived from a SettlementIntent. + +Hash computation uses **domain‑separated hashing** consistent with MPCP artifacts. + +``` +intentHash = SHA256( + "MPCP:SettlementIntent:1.0:" || canonicalJson(canonicalIntent) +) +``` + +Domain separation ensures the hash cannot collide with other MPCP artifact hashes. + +--- + +## Canonical Hash Payload + +The intent hash MUST be computed from a **canonical payload** containing only fields that define the **settlement semantics**. + +Metadata fields MUST be excluded. + +Default canonical payload fields: + +- version +- rail +- asset (if present) +- amount +- destination (if present) +- referenceId (if present) + +The following fields MUST NOT participate in canonical hashing under the default MPCP profile: + +- createdAt + +Example canonical payload: + +```json +{ + "version": "1.0", + "rail": "xrpl", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer..." + }, + "amount": "19440000", + "destination": "rDestination...", + "referenceId": "quote_17" +} +``` + +This ensures that two semantically identical intents produce the same `intentHash` even if metadata such as `createdAt` differs. + +Implementations MAY define extended profiles where metadata fields participate in hashing, but such profiles MUST be explicitly documented and versioned. + +--- + +## Canonical JSON + +Implementations MUST compute the hash using a canonical JSON representation of the canonical payload defined above (not the full artifact). + +Requirements: + +- stable key ordering +- no whitespace variation +- UTF‑8 encoding + +Example (conceptual): + +``` +canonicalJson(intent) +``` + +--- + +## Relationship to SPA + +A **SignedPaymentAuthorization (SPA)** may include `intentHash`. + +When present, the SPA verifier must ensure: + +``` +intentHash == SHA256("MPCP:SettlementIntent::" || canonicalJson(intent)) +``` + +This binds the SPA to a specific settlement intent. + +--- + +## Verification + +A settlement verifier must ensure that the executed payment matches the SettlementIntent. + +Checks typically include: + +- rail matches +- asset matches (if applicable) +- destination matches (if applicable) +- amount matches + +If the SPA contains an `intentHash`, the verifier must also recompute the hash and ensure it matches the SPA. + +--- + +## Rail Semantics + +Different rails use different subsets of the intent fields. + +| Rail | asset | destination | +|-----|------|-------------| +| xrpl | required | required | +| evm | required | required | +| stripe | omitted | omitted | +| hosted | omitted | omitted | + +Implementations must enforce the correct field requirements for the selected rail. + +--- + +## Summary + +SettlementIntent defines the canonical payment description used to bind authorizations to deterministic settlement parameters. + +By hashing the intent and embedding the hash into signed artifacts, MPCP ensures that the executed payment cannot diverge from the authorized parameters. + +--- + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Demonstrates how SettlementIntent is used during runtime authorization. diff --git a/docs/protocol/SettlementIntentHash.md b/docs/protocol/SettlementIntentHash.md new file mode 100644 index 00000000..29d276da --- /dev/null +++ b/docs/protocol/SettlementIntentHash.md @@ -0,0 +1,142 @@ +# SettlementIntentHash + +Part of the [Machine Payment Control Protocol (MPCP)](./mpcp.md). + +The **intentHash** is an optional field in the SignedPaymentAuthorization (SPA) that binds the authorization to a canonical settlement intent. + +When present, it ensures the executed settlement matches the authorized intent. + +--- + +## Definition + +``` +intentHash = SHA256( + "MPCP:SettlementIntent:1.0:" || canonicalJson(canonicalIntent) +) +``` + +- **canonicalJson**: Deterministic JSON serialization (sorted keys, omit null/undefined) +- **SHA256**: Output as hex string + +## Canonical Hash Payload + +The intent hash MUST be computed from a **canonical payload** that includes only the fields defining the settlement semantics. + +Metadata fields present in the artifact MUST be excluded from the hash input. + +Default canonical payload fields: + +- version +- rail +- asset (if present) +- amount +- destination (if present) +- referenceId (if present) + +The following fields MUST NOT participate in hashing under the default MPCP profile: + +- createdAt + +Example canonical payload: + +```json +{ + "version": "1.0", + "rail": "xrpl", + "asset": { "kind": "IOU", "currency": "USDC", "issuer": "rIssuer..." }, + "amount": "19440000", + "destination": "rDest...", + "referenceId": "quote_17" +} +``` + + +See also: [SettlementIntent.md](./SettlementIntent.md) §Canonical Hash Payload. + +--- + +## Purpose + +1. **Binding** — The SPA authorizes a specific settlement. The intentHash commits to the exact intent structure. +2. **Verification** — A verifier can check that the executed settlement corresponds to the intent by recomputing the hash. +3. **Replay protection** — The intent is uniquely bound to the authorization. + +--- + +## Canonical JSON Rules + +Per the MPCP spec, canonicalJson is applied to the canonical payload defined above: + +- Sorts object keys lexicographically +- Omits fields with `null` or `undefined` values +- Recursively canonicalizes nested objects and arrays + +--- + +## Example + +### Settlement intent (rail-specific) + +```json +{ + "version": "1.0", + "rail": "xrpl", + "destination": "rDest...", + "amount": "19440000", + "asset": { "kind": "IOU", "currency": "USDC", "issuer": "rIssuer..." }, + "createdAt": "2026-03-08T13:55:00Z" +} +``` + +### Computation + +```text +canonicalIntent = canonicalJson({ + version, + rail, + asset, + amount, + destination +}) +intentHash = sha256Hex("MPCP:SettlementIntent:1.0:" || canonicalIntent) +``` + +### SPA with intentHash + +```json +{ + "authorization": { + "version": "1.0", + "decisionId": "dec_123", + "sessionId": "sess_456", + "rail": "xrpl", + "asset": { "kind": "IOU", "currency": "USDC", "issuer": "rIssuer..." }, + "amount": "19440000", + "destination": "rDest...", + "intentHash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "expiresAt": "2026-03-08T14:00:00Z" + }, + "signature": "...", + "keyId": "mpcp-spa-signing-key-1" +} +``` + +--- + +## Verification + +When an SPA includes `intentHash`: + +1. The verifier MUST be given the `settlementIntent` used at authorization time (or the executed settlement in intent form). +2. The verifier computes `computeIntentHash(settlementIntent)`. +3. The verifier MUST reject if the computed hash does not match `authorization.intentHash`. + +If `intentHash` is absent, the verifier checks only the explicit fields (amount, rail, asset, destination) against the settlement. + +--- + +## Optional vs Required + +- **Optional** — SPAs may omit `intentHash` when the intent structure is not needed or when verification is done by policy-only matching. +- **Recommended** — When the settlement intent is known at authorization time, include `intentHash` for stronger binding and replay protection. diff --git a/docs/protocol/SignedBudgetAuthorization.md b/docs/protocol/SignedBudgetAuthorization.md new file mode 100644 index 00000000..ffb85b94 --- /dev/null +++ b/docs/protocol/SignedBudgetAuthorization.md @@ -0,0 +1,139 @@ +# SignedBudgetAuthorization (SBA) + +Artifact Type: MPCP:SBA + +Part of the [Machine Payment Control Protocol (MPCP)](./mpcp.md). + +## Purpose + +The **SignedBudgetAuthorization (SBA)** defines a signed spending envelope for a machine payment scope. + +It is a protocol-level MPCP artifact that constrains subsequent **SignedPaymentAuthorization (SPA)** artifacts. + +Unlike application-specific budget concepts, SBA is generic and may be used across parking, charging, tolling, robotics, AI agents, and other machine-payment environments. + +The **SignedBudgetAuthorization (SBA)** establishes the maximum spending envelope available to a machine for a defined payment scope. + +It is issued after a PolicyGrant and constrains subsequent SignedPaymentAuthorizations (SPAs). + +--- + +## Structure + +### BudgetAuthorization (inner payload) + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| version | string | yes | MPCP semantic version (e.g. "1.0") | +| budgetId | string | yes | Unique identifier for this budget | +| sessionId | string | yes | Session this budget applies to | +| vehicleId | string | yes | Vehicle identifier | +| scopeId | string | no | Optional scope identifier | +| policyHash | string | yes | Hash of the policy that authorized this budget | +| currency | string | yes | Reference currency (e.g. "USD") | +| minorUnit | number | yes | Decimal scale (e.g. 2) | +| budgetScope | string | yes | SESSION \| DAY \| VEHICLE \| FLEET | +| maxAmountMinor | string | yes | Maximum spend in minor units | +| allowedRails | Rail[] | yes | Permitted payment rails (xrpl, evm, stripe, hosted) | +| allowedAssets | Asset[] | yes | Permitted assets | +| destinationAllowlist | string[] | no | Optional allowed destination addresses | +| expiresAt | string | yes | ISO 8601 expiration timestamp | + +### SignedBudgetAuthorization (envelope) + +| Field | Type | Description | +|-------|------|-------------| +| authorization | BudgetAuthorization | The budget payload | +| signature | string | Base64-encoded signature over SHA256("MPCP:SBA:1.0:" || canonicalJson(authorization)) | +| keyId | string | Signing key identifier for verification | + +--- + +## Scope Model + +SBA supports multiple budget scopes. + +| Scope | Meaning | +|------|---------| +| SESSION | Budget applies to a single session | +| DAY | Budget applies across sessions for a day | +| VEHICLE | Budget applies across sessions for a specific vehicle | +| FLEET | Budget applies across vehicles within a fleet authority | + +When present, `scopeId` identifies the entity the budget applies to. + +Examples: + +- `budgetScope: "SESSION"` with `scopeId` = session identifier +- `budgetScope: "VEHICLE"` with `scopeId` = vehicle identifier +- `budgetScope: "FLEET"` with `scopeId` = fleet identifier + +## Example + +```json +{ + "authorization": { + "version": "1.0", + "budgetId": "550e8400-e29b-41d4-a716-446655440000", + "sessionId": "sess_456", + "vehicleId": "veh_001", + "policyHash": "a1b2c3...", + "currency": "USD", + "minorUnit": 2, + "budgetScope": "SESSION", + "maxAmountMinor": "3000", + "allowedRails": ["xrpl"], + "allowedAssets": [{ "kind": "IOU", "currency": "USDC", "issuer": "rIssuer..." }], + "destinationAllowlist": ["rDest..."], + "expiresAt": "2026-03-08T14:00:00Z" + }, + "signature": "base64...", + "keyId": "mpcp-sba-signing-key-1" +} +``` + +--- + +## Verification + +All MPCP signatures MUST use domain-separated hashing before signing. + +For SBA artifacts the domain prefix is: + +``` +MPCP:SBA:: +``` + +Example hash computation: + +``` +hash = SHA256("MPCP:SBA:1.0:" || canonicalJson(authorization)) +``` + +This prevents cross-protocol and cross-artifact hash collisions and ensures compatibility with MPCP verifier implementations. + +A verifier MUST: + +1. Validate the signature over SHA256("MPCP:SBA::" || canonicalJson(authorization)) using the public key for `keyId` +2. Check `expiresAt` has not passed +3. When verifying against a payment decision or settlement context: ensure sessionId, policyHash, budgetScope, allowedRails, allowedAssets, optional destination constraints, and amount constraints match + +--- + +## Relationship to Pipeline + +``` +PolicyGrant + ↓ +SignedBudgetAuthorization (SBA) + ↓ +SignedPaymentAuthorization (SPA) + ↓ +Settlement +``` + +--- + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Demonstrates how SBA is used during runtime authorization. diff --git a/docs/protocol/SignedPaymentAuthorization.md b/docs/protocol/SignedPaymentAuthorization.md new file mode 100644 index 00000000..686f0584 --- /dev/null +++ b/docs/protocol/SignedPaymentAuthorization.md @@ -0,0 +1,140 @@ +# SignedPaymentAuthorization (SPA) + +Artifact Type: MPCP:SPA + +Part of the [Machine Payment Control Protocol (MPCP)](./mpcp.md). + +## Purpose + +The **SignedPaymentAuthorization (SPA)** is a cryptographically signed authorization that permits a specific settlement transaction. + +It binds the payment parameters (rail, asset, amount, destination) to a prior policy decision and optionally binds the authorization to a canonical settlement intent via `intentHash`. + +SPA makes payment decisions: + +- portable +- verifiable +- deterministic +- safe for autonomous agents + +Instead of trusting UI state or API responses, the payer executes a payment that is bound to a **signed authorization artifact**. + +SPA is a protocol artifact and is not tied to any specific application implementation. + +--- + +## Structure + +### PaymentAuthorization (inner payload) + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| version | string | yes | MPCP semantic version (e.g. "1.0") | +| decisionId | string | yes | Payment policy decision identifier | +| sessionId | string | yes | Session identifier | +| policyHash | string | yes | Hash of the policy | +| quoteId | string | yes | Settlement quote identifier | +| rail | Rail | yes | Payment rail (xrpl, evm, stripe, hosted) | +| asset | Asset | conditional | Required for on-chain rails (xrpl, evm); omitted for hosted rails | +| amount | string | yes | Amount in atomic units | +| destination | string | conditional | Required for on-chain rails; not required for hosted rails | +| intentHash | string | no | SHA256 hex of canonical settlement intent (optional) | +| expiresAt | string | yes | ISO 8601 expiration timestamp | + +### SignedPaymentAuthorization (envelope) + +| Field | Type | Description | +|-------|------|-------------| +| authorization | PaymentAuthorization | The payment payload | +| signature | string | Base64-encoded signature over SHA256("MPCP:SPA:1.0:" || canonicalJson(authorization)) | +| keyId | string | Signing key identifier for verification | + +--- + +## Example + +```json +{ + "authorization": { + "version": "1.0", + "decisionId": "dec_123", + "sessionId": "sess_456", + "policyHash": "a1b2c3...", + "quoteId": "quote_789", + "rail": "xrpl", + "asset": { "kind": "IOU", "currency": "USDC", "issuer": "rIssuer..." }, + "amount": "19440000", + "destination": "rDest...", + "intentHash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "expiresAt": "2026-03-08T14:00:00Z" + }, + "signature": "base64...", + "keyId": "mpcp-spa-signing-key-1" +} +``` + +--- + +## Rail Semantics + +Different payment rails require different subsets of the authorization fields. + +| Rail | asset | destination | Notes | +|-----|------|-------------|------| +| xrpl | required | required | XRPL payments require issuer/currency and destination address | +| evm | required | required | ERC‑20 or native asset transfer to a destination address | +| stripe | omitted | omitted | Stripe settlement determined by backend charge request | +| hosted | omitted | omitted | Hosted payment session resolves settlement parameters | + +Implementations MUST enforce the field requirements appropriate for the selected rail. + +For on‑chain rails (`xrpl`, `evm`) the verifier must check: + +- asset matches the executed transaction +- destination matches the executed transaction +- amount matches the authorized amount + +For hosted rails the verifier checks settlement against the backend payment record. + +## Verification + +All MPCP signatures use domain‑separated hashing before signing. + +For SPA artifacts the domain prefix is: + +MPCP:SPA:: + +Example hash computation: + +hash = SHA256("MPCP:SPA:1.0:" || canonicalJson(authorization)) + +This prevents cross‑artifact and cross‑protocol hash collisions. + +A verifier MUST: + +1. Validate the signature over SHA256("MPCP:SPA::" || canonicalJson(authorization)) using the public key for `keyId` +2. Check `expiresAt` has not passed +3. When verifying against a SettlementResult: ensure decisionId, rail, amount, destination, and asset match +4. If `intentHash` is present: verify it equals `computeIntentHash(settlementIntent)` for the provided intent + +--- + +## Relationship to Pipeline + +``` +SignedBudgetAuthorization (SBA) + ↓ +SignedPaymentAuthorization (SPA) + ↓ +Settlement Execution + ↓ +Settlement Verification +``` + +See [SettlementIntentHash](./SettlementIntentHash.md) for details on the optional intent binding. + +--- + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Demonstrates how SPA is used during runtime authorization. diff --git a/docs/protocol/hashing.md b/docs/protocol/hashing.md index abe86418..e5af3658 100644 --- a/docs/protocol/hashing.md +++ b/docs/protocol/hashing.md @@ -59,6 +59,6 @@ Metadata (e.g., `createdAt`) is excluded from the hash. ## See Also -- [SettlementIntentHash spec](../doc/protocol/SettlementIntentHash.md) +- [SettlementIntentHash spec](SettlementIntentHash.md) - [Verification](verification.md) - [Anchoring](anchoring.md) diff --git a/docs/protocol/mpcp.md b/docs/protocol/mpcp.md new file mode 100644 index 00000000..cc2166b4 --- /dev/null +++ b/docs/protocol/mpcp.md @@ -0,0 +1,1062 @@ +# Machine Payment Control Protocol (MPCP) + +## Overview + +The **Machine Payment Control Protocol (MPCP)** defines a cryptographically enforced pipeline for autonomous or software-controlled payments. + +The protocol enables machines (vehicles, robots, services, AI agents, or IoT devices) to perform financial transactions while remaining constrained by deterministic policies. + +Unlike traditional payment systems that rely on trusted intermediaries, MPCP enforces spending constraints through a sequence of signed authorization artifacts that are verified before settlement. + +The protocol introduces a structured authorization flow: + +Policy → Grant → Budget Authorization → Payment Authorization → Settlement Verification → Optional Public Attestation + +This architecture ensures that machine-initiated payments remain bounded, auditable, and verifiable. + +--- + +# Motivation + +Autonomous systems increasingly participate in economic activity. + +Examples include: + +- autonomous vehicles paying for parking, tolls, or charging +- delivery robots purchasing access to infrastructure +- IoT devices paying for services or resources +- AI agents executing automated purchases +- fleet-operated vehicles performing operational payments + +Traditional payment systems are not designed for these environments because they assume a human actor approving each transaction. + +Machine payments require a different model where: + +- policies are defined ahead of time +- spending is constrained cryptographically +- authorization artifacts can be verified independently +- settlement can be audited after execution + +MPCP provides this control layer. + +--- + +# Core Design Principles + +The protocol is built around the following principles: + +### Policy First + +All payments must derive from explicit policy rules. + +Policies may define: + +- allowed operators +- allowed payment rails +- allowed assets +- geographic restrictions +- spending limits +- approval requirements + +### Bounded Autonomy + +Machines may execute payments autonomously but only within policy-defined limits. + +### Cryptographic Authorization + +Each stage of the pipeline produces a signed artifact that constrains the next stage. + +### Deterministic Verification + +Settlement transactions must be verifiable against the authorization artifacts. + +### Optional Public Attestation + +Intent commitments can optionally be anchored to a public ledger for additional audit guarantees. + +--- + +# Protocol Versioning & Compatibility + +## Version Field + +All MPCP artifacts SHOULD include a semantic version string in the `version` field. + +Example: + +```json +{ + "version": "1.0", + "decisionId": "dec_123", + ... +} +``` + +The version identifies the protocol semantics used when producing the artifact. + +--- + +## Versioning Model + +MPCP uses semantic versioning: **MAJOR.MINOR** + +Example: `1.0`, `1.1`, `2.0` + +### Minor Versions + +Minor versions may: + +- add optional fields +- extend artifact structures +- introduce new rails or assets + +Minor upgrades MUST remain backward compatible. + +Verifiers MUST ignore unknown optional fields. + +### Major Versions + +Major versions may: + +- change artifact semantics +- modify verification rules +- alter canonicalization requirements + +Verifiers MUST reject artifacts whose major version they do not support. + +--- + +## Forward Compatibility + +Implementations MUST: + +- ignore unknown optional fields +- preserve unknown fields when forwarding artifacts + +This ensures MPCP artifacts remain interoperable between different implementations. + +--- + +## Artifact Version Propagation + +Artifacts SHOULD propagate the version they were produced under. + +Example chain: + +```text +PolicyGrant.version + ↓ +SBA.version + ↓ +SPA.version +``` + +A verifier MAY reject chains containing mixed incompatible versions. + +--- + +## Reference Version + +The MPCP specification in this repository defines: + +**Protocol Version: 1.0** + +--- + +# Protocol Pipeline + +The protocol operates as a multi-stage authorization pipeline. + +```text +Policy Engine + ↓ +PolicyGrant + ↓ +SignedBudgetAuthorization (SBA) + ↓ +SignedPaymentAuthorization (SPA) + ↓ +Settlement Execution + ↓ +Settlement Verification + ↓ +Optional Intent Attestation +``` + +Each stage cryptographically binds the parameters for the following stage. +In MPCP, every settlement must be authorized by a deterministic chain of artifacts that progressively constrain the transaction parameters. + +--- + +## Implementer Checklist + +An implementation claiming MPCP compatibility MUST support the following capabilities. + +### Artifact Handling + +Implementations MUST be able to parse and validate the following artifacts: + +- PolicyGrant +- SignedBudgetAuthorization (SBA) +- SignedPaymentAuthorization (SPA) +- SettlementIntent +- IntentCommitment (optional) + +### Canonical JSON + +Implementations MUST produce identical hashes for the same artifact data. + +Requirements: + +- lexicographically sorted keys +- no insignificant whitespace +- UTF-8 encoding +- omit `null` / `undefined` fields +- monetary values encoded as strings + +### Hash Domain Separation + +Hashes MUST include the MPCP domain prefix. + +Example (SettlementIntent uses a canonical payload — subset of fields, not the full artifact; see [SettlementIntentHash.md](./SettlementIntentHash.md)): + +```text +SHA256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) +``` + +--- + +## Protocol Artifacts + +The MPCP pipeline produces a series of structured artifacts. Each artifact constrains the next stage of the protocol and can be independently verified. + +### PolicyGrant + +The **PolicyGrant** represents the admission of a machine into a controlled payment context. + +Example structure: + +```json +{ + "version": "1.0", + "grantId": "grant_abc123", + "vehicleId": "veh_001", + "operatorId": "operator_42", + "lotId": "lot_7", + "allowedRails": ["xrpl"], + "allowedAssets": ["RLUSD"], + "policyHash": "sha256(...)", + "expiresAt": "2026-03-08T14:00:00Z" +} +``` + +The PolicyGrant defines the operational scope in which further authorizations may be issued. + +--- + +### SignedBudgetAuthorization (SBA) + +The **SignedBudgetAuthorization (SBA)** establishes the maximum spending envelope available to the machine. + +Example structure: + +```json +{ + "version": "1.0", + "budgetId": "budget_123", + "grantId": "grant_abc123", + "sessionId": "sess_456", + "scopeId": "sess_456", + "budgetScope": "SESSION", + "currency": "USD", + "minorUnit": 2, + "maxAmountMinor": "3000", + "allowedRails": ["xrpl"], + "allowedAssets": ["RLUSD"], + "expiresAt": "2026-03-08T14:00:00Z", + "signature": "..." +} +``` + +The SBA ensures that spending remains within defined limits. + +--- + +### SignedPaymentAuthorization (SPA) + +The **SignedPaymentAuthorization (SPA)** authorizes a specific settlement transaction. + +Example structure: + +```json +{ + "version": "1.0", + "decisionId": "dec_123", + "budgetId": "budget_123", + "sessionId": "sess_456", + "rail": "xrpl", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer..." + }, + "amount": "19440000", + "destination": "rDest...", + "intentHash": "sha256(...)", + "expiresAt": "2026-03-08T14:00:00Z", + "signature": "..." +} +``` + +The SPA binds the authorized payment parameters and optionally includes an `intentHash` to bind the authorization to a canonical settlement intent. + +--- + +### SettlementIntent + +A **SettlementIntent** describes the canonical form of the transaction that the machine wallet must execute. + +Example structure: + +```json +{ + "version": "1.0", + "rail": "xrpl", + "destination": "rDest...", + "amount": "19440000", + "currency": "RLUSD", + "issuer": "rIssuer...", + "memo": { + "type": "mpcp", + "decisionId": "dec_123" + } +} +``` + +This structure is used to compute the `intentHash`. + +--- + +### IntentCommitment + +An **IntentCommitment** represents the hashed commitment of the settlement intent. + +Example: + +```text +commitment = SHA256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) +``` + +IntentCommitment represents the canonical MPCP artifact used when publishing commitments to an external attestation system such as the Intent Attestation Layer (IAL). +Commitments may optionally be published to the **Intent Attestation Layer (IAL)** to create a publicly verifiable record that the intent existed prior to settlement. + +--- + +## Artifact Relationships + +The protocol artifacts form a dependency chain. Each artifact references the previous stage and constrains the next. + +```text +PolicyGrant + ↓ +SignedBudgetAuthorization (references grantId) + ↓ +SignedPaymentAuthorization (references budgetId) + ↓ +SettlementIntent (referenced by intentHash) + ↓ +IntentCommitment (hash of SettlementIntent) +``` + +### Relationship Rules + +**PolicyGrant → SBA** + +- `SBA.grantId` MUST reference a valid `PolicyGrant.grantId` +- the SBA must respect the rail, asset, and policy constraints of the grant + +**SBA → SPA** + +- `SPA.budgetId` MUST reference the issuing SBA +- `SPA.amount` MUST be ≤ `SBA.maxAmountMinor` +- `SPA.rail` MUST be included in `SBA.allowedRails` + +**SPA → SettlementIntent** + +- the settlement intent must match the payment parameters authorized in the SPA +- if present, `SPA.intentHash` MUST equal: + +```text +SHA256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) +``` + + (canonicalPayload = subset of intent fields defining settlement semantics; see [SettlementIntentHash.md](./SettlementIntentHash.md)) + +**SettlementIntent → IntentCommitment** + +- the commitment is derived deterministically from the canonical intent +- commitments may be published to the Intent Attestation Layer (IAL) + +These relationships ensure that each stage of MPCP cryptographically and logically constrains the following stage, preventing unauthorized mutations or spending outside policy limits. + +--- + +# Settlement Verification + +Before accepting settlement, the system verifies: + +- SPA signature validity +- policy hash consistency +- asset match +- destination match +- amount constraints +- authorization expiration +- settlement intent match + +--- + +## Verification Algorithm + +An MPCP verifier MUST perform the following steps before accepting settlement. + +### Step 1 — Verify SPA Signature + +Verify the cryptographic signature on the **SignedPaymentAuthorization (SPA)**. + +```text +verify_signature(spa.signature, spa.payload, policyAuthorityPublicKey) +``` + +If signature verification fails → **reject settlement**. + +--- + +### Step 2 — Verify Grant and Budget Lineage + +Ensure that the authorization chain is valid. + +```text +spa.budgetId → SignedBudgetAuthorization +sba.grantId → PolicyGrant +``` + +Verification rules: + +- `SPA.budgetId` MUST reference an existing SBA +- `SBA.grantId` MUST reference an existing PolicyGrant +- artifacts MUST NOT be expired + +If lineage is invalid → **reject settlement**. + +--- + +### Step 3 — Verify Policy Constraints + +Confirm the settlement parameters match the authorized constraints. + +Checks include: + +- rail match +- asset match +- destination match +- amount ≤ authorized limit +- policyHash consistency + +If any constraint fails → **reject settlement**. + +--- + +### Step 4 — Verify Intent Binding (Optional) + +If the SPA contains an `intentHash`, the verifier must reconstruct the canonical payload (subset of intent fields) and compare hashes. + +```text +computedHash = SHA256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) +``` + +Verification rule: + +```text +computedHash == SPA.intentHash +``` + +If mismatch → **reject settlement**. + +--- + +### Step 5 — Verify Expiration + +Check expiration fields: + +- `PolicyGrant.expiresAt` +- `SBA.expiresAt` +- `SPA.expiresAt` + +If any artifact is expired → **reject settlement**. + +--- + +### Step 6 — Verify Settlement Transaction + +Extract parameters from the executed settlement transaction and confirm they match the SPA. + +Checks include: + +- destination +- amount +- asset +- rail + +If settlement parameters differ from SPA → **reject settlement**. + +--- + +### Step 7 — Accept Settlement + +If all verification steps succeed: + +```text +accept settlement +record session close +emit settlement event +``` + +Optional: + +- produce `IntentCommitment` +- publish commitment to the **Intent Attestation Layer (IAL)**. + +--- + +# Canonical JSON Definition + +## Protocol Identifier & Domain Separation + +To prevent cross‑protocol hash collisions, MPCP implementations MUST apply **domain separation** when hashing protocol artifacts. + +Hash inputs MUST be prefixed with a protocol‑specific identifier before hashing. + +Recommended format: + +```text +MPCP::: +``` + +Example: + +```text +MPCP:SettlementIntent:1.0:{"amount":"19440000","destination":"rDest...","rail":"xrpl"} +``` + +Hash computation therefore becomes (canonicalPayload = subset of intent fields; see [SettlementIntentHash.md](./SettlementIntentHash.md)): + +```text +intentHash = SHA256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) +``` + +This ensures: + +- MPCP hashes cannot collide with hashes from other protocols +- different MPCP artifact types produce distinct hash domains +- future protocol versions remain cryptographically isolated + +Implementations MUST apply the same domain prefix rules when generating and verifying hashes. + +The version component in the domain prefix MUST use the same semantic version string carried in the artifact, for example `1.0`, `1.1`, or `2.0`. This keeps hashing behavior aligned with MPCP version negotiation and prevents ambiguity between artifact formats. + +To ensure deterministic hashing across systems, MPCP defines a **canonical JSON encoding** used when computing hashes such as `intentHash`. + +All implementations MUST apply the same canonicalization rules before hashing. + +Canonicalization rules: + +1. Object keys MUST be sorted lexicographically. +2. No insignificant whitespace is allowed. +3. Numbers MUST be encoded as strings when representing monetary values. +4. Unicode strings MUST be UTF-8 encoded. +5. Fields with `null` or `undefined` values MUST be omitted. + +Example: + +Input object: + +```json +{ + "destination": "rDest...", + "amount": "19440000", + "rail": "xrpl" +} +``` + +Canonical form: + +```text +{"amount":"19440000","destination":"rDest...","rail":"xrpl"} +``` + +Hash computation (canonicalPayload excludes metadata such as createdAt): + +```text +intentHash = SHA256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) +``` + +--- + +# Signature Schemes + +MPCP supports multiple cryptographic signature schemes depending on the environment in which the policy authority operates. + +Implementations SHOULD support at least one of the following: + +### Ed25519 + +Recommended for most policy authorities. + +Advantages: + +- fast verification +- small signatures +- widely supported + +### secp256k1 + +Common in blockchain systems including: + +- Bitcoin +- Ethereum +- many EVM chains + +Useful when authorization artifacts must be verified by smart contracts. + +### XRPL Native Signatures + +For XRPL-integrated environments, SPA artifacts may be signed using XRPL-compatible keypairs. + +Implementations MAY also support XRPL multisign accounts for fleet-level authorization control. + +Signature verification MUST validate: + +- payload integrity +- signer identity +- signature scheme compatibility + +--- + +# Replay Protection + +MPCP must prevent the reuse of authorization artifacts across multiple settlements. + +The following replay protections MUST be implemented. + +### Decision ID Uniqueness + +Each **SPA** contains a `decisionId`. + +Rules: + +- `decisionId` MUST be globally unique +- verifiers MUST reject reuse of a previously consumed `decisionId` + +### Intent Hash Binding + +When present, the `intentHash` binds the SPA to a specific settlement intent. + +This prevents mutation of: + +- amount +- destination +- asset +- memo fields + +### Transaction Binding + +Implementations SHOULD record the settlement transaction identifier. + +Examples: + +- XRPL `txHash` +- Ethereum `transactionHash` +- Lightning payment hash + +Once a transaction hash is associated with an SPA, the authorization MUST NOT be reused. + +--- + +# Threat Model + +The MPCP protocol is designed to mitigate the following threats. + +### Unauthorized Machine Spending + +A compromised machine wallet cannot exceed authorized budgets because: + +- payments require a valid SPA +- SPA amounts are bounded by the SBA + +### Transaction Mutation + +An attacker modifying settlement parameters will invalidate: + +- intent hashes +- asset checks +- destination checks + +### Replay Attacks + +Expired or previously used authorizations cannot be reused due to: + +- expiration checks +- decisionId uniqueness +- transaction binding + +### Policy Bypass + +Machines cannot bypass policy constraints because every authorization chain must derive from: + +```text +PolicyGrant → SBA → SPA +``` + +### Settlement Tampering + +Verification ensures that executed settlement transactions match authorized parameters before the session is finalized. + +--- + +These sections define the core interoperability rules required for MPCP implementations across different systems and settlement rails. + +--- + +# Wire Formats + +This section defines the canonical wire-format expectations for MPCP artifacts. + +All artifacts SHOULD be represented as UTF-8 JSON documents using the canonical JSON rules defined above when used for hashing or signing. + +## PolicyGrant Wire Format + +```json +{ + "version": "1.0", + "grantId": "grant_abc123", + "vehicleId": "veh_001", + "operatorId": "operator_42", + "lotId": "lot_7", + "allowedRails": ["xrpl"], + "allowedAssets": ["RLUSD"], + "policyHash": "sha256(...)", + "expiresAt": "2026-03-08T14:00:00Z" +} +``` + +## SignedBudgetAuthorization Wire Format + +```json +{ + "version": "1.0", + "budgetId": "budget_123", + "grantId": "grant_abc123", + "sessionId": "sess_456", + "scopeId": "sess_456", + "budgetScope": "SESSION", + "currency": "USD", + "minorUnit": 2, + "maxAmountMinor": "3000", + "allowedRails": ["xrpl"], + "allowedAssets": ["RLUSD"], + "expiresAt": "2026-03-08T14:00:00Z", + "signature": "..." +} +``` + +## SignedPaymentAuthorization Wire Format + +```json +{ + "version": "1.0", + "decisionId": "dec_123", + "budgetId": "budget_123", + "sessionId": "sess_456", + "rail": "xrpl", + "asset": { + "kind": "IOU", + "currency": "RLUSD", + "issuer": "rIssuer..." + }, + "amount": "19440000", + "destination": "rDest...", + "intentHash": "sha256(...)", + "expiresAt": "2026-03-08T14:00:00Z", + "signature": "..." +} +``` + +## SettlementIntent Wire Format + +```json +{ + "version": "1.0", + "rail": "xrpl", + "destination": "rDest...", + "amount": "19440000", + "currency": "RLUSD", + "issuer": "rIssuer...", + "memo": { + "type": "mpcp", + "decisionId": "dec_123" + } +} +``` + +## IntentCommitment Wire Format + +```json +{ + "version": "1.0", + "intentHash": "sha256(...)", + "batchId": "batch_001", + "merkleRoot": "sha256(...)", + "anchorNetwork": "hedera-hcs", + "anchorReference": "topic:0.0.12345/sequence:678", + "consensusTimestamp": "2026-03-08T14:00:05Z" +} +``` + +## Artifact Bundle + +An **artifact bundle** packages complete payment verification data (policyGrant, sba, spa, settlement, optional settlementIntent and ledgerAnchor) into a single JSON object for exchange between systems. See [ArtifactBundle.md](./ArtifactBundle.md) for the canonical format and schema. + +--- + +# Error Codes + +MPCP implementations SHOULD expose stable machine-readable error codes during verification and settlement rejection. + +Recommended codes: + +| Code | Meaning | +|------|---------| +| SPA_SIGNATURE_INVALID | SPA signature verification failed | +| SBA_SIGNATURE_INVALID | SBA signature verification failed | +| POLICY_GRANT_NOT_FOUND | Referenced PolicyGrant does not exist | +| SBA_NOT_FOUND | Referenced SBA does not exist | +| SPA_NOT_FOUND | Referenced SPA does not exist | +| ARTIFACT_EXPIRED | One or more artifacts expired | +| POLICY_HASH_MISMATCH | Policy hash does not match authorized policy | +| RAIL_MISMATCH | Settlement rail differs from authorization | +| ASSET_MISMATCH | Settlement asset differs from authorization | +| DESTINATION_MISMATCH | Settlement destination differs from authorization | +| AMOUNT_EXCEEDED | Settlement amount exceeds authorized limit | +| INTENT_HASH_MISMATCH | Canonical settlement intent hash does not match SPA | +| DECISION_REPLAYED | decisionId has already been consumed | +| TX_REPLAYED | settlement transaction identifier has already been consumed | +| SCOPE_UNSUPPORTED | Authorization scope is not supported by the verifier | + +Error codes SHOULD remain stable across implementations whenever possible to preserve interoperability. + +--- + +# Reference Verification Pseudocode + +The following pseudocode illustrates a minimal verifier implementation. + +```text +function verifySettlement(grant, sba, spa, settlementTx): + verifySignature(spa) + verifyLineage(grant, sba, spa) + verifyNotExpired(grant, sba, spa) + verifyPolicyHash(grant, spa) + verifyBudgetConstraints(sba, spa) + verifySettlementFields(spa, settlementTx) + + if spa.intentHash is present: + canonicalPayload = extractCanonicalPayload(settlementTx) # subset of fields, not full artifact + computedHash = sha256("MPCP:SettlementIntent:1.0:" || canonical_json(canonicalPayload)) + assert computedHash == spa.intentHash + + assert decisionIdNotConsumed(spa.decisionId) + assert txIdNotConsumed(settlementTx.id) + + markDecisionConsumed(spa.decisionId) + bindTransaction(spa.decisionId, settlementTx.id) + acceptSettlement() +``` + +This pseudocode is illustrative only. Production systems may split verification across multiple services. + +--- + +# State Machine + +MPCP authorization and settlement artifacts move through a small set of states. + +## PolicyGrant + +```text +ISSUED → EXPIRED +``` + +## SignedBudgetAuthorization + +```text +ISSUED → EXPIRED +``` + +## SignedPaymentAuthorization + +```text +ISSUED → CONSUMED +ISSUED → EXPIRED +ISSUED → REJECTED +``` + +## Settlement + +```text +PENDING → VERIFIED +PENDING → REJECTED +``` + +## State Machine Rules + +- A consumed SPA MUST NOT be reused. +- An expired grant, SBA, or SPA MUST NOT authorize settlement. +- A verified settlement MUST bind to exactly one `decisionId`. +- A rejected settlement MUST NOT advance the session to a closed state. + +This state model keeps MPCP deterministic and makes replay protection enforceable. + +--- + +# Optional Intent Attestation + +To enhance auditability, MPCP can publish hashed commitments of payment intents to a public attestation layer. + +Example flow: + +```text +intent + ↓ +hash(intent) + ↓ +Merkle tree + ↓ +public ledger anchor +``` + +This provides: + +- tamper-evident authorization history +- public timestamp proofs +- dispute resolution capabilities + +The **Intent Attestation Layer (IAL)** can provide this functionality. + +--- + +# Security Properties + +The protocol prevents: + +- unauthorized machine spending +- transaction mutation attacks +- replay of expired authorizations +- exceeding policy budgets +- unauthorized settlement destinations + +Because each stage is cryptographically bound, a machine cannot bypass constraints without invalidating verification. + +--- + +# Applications + +MPCP can be applied across many autonomous payment scenarios: + +- parking systems +- EV charging networks +- tolling infrastructure +- robotic logistics +- fleet management +- IoT service payments +- AI agent marketplaces + +--- + +# Parker as Reference Implementation + +The Parker system implements MPCP for autonomous parking payments. + +Its architecture demonstrates how policy enforcement, authorization artifacts, and settlement verification can operate together. + +Parker therefore serves as a reference implementation for the Machine Payment Control Protocol. + +--- + +# Protocol Extensions + +MPCP may be extended through additional authorization artifacts that introduce new policy authorities or control layers. + +Extensions MUST preserve the core MPCP lineage model and MUST NOT weaken the verification guarantees defined by the protocol. + +Current extensions include: + +## FleetPolicyAuthorization (FPA) + +FleetPolicyAuthorization introduces **fleet‑side policy authority** into MPCP. + +In many real-world deployments, machines operate under the control of a **fleet operator** rather than directly under the service provider issuing the PolicyGrant. +Examples include: + +- robotaxi fleets +- delivery fleets +- logistics robots +- autonomous trucking + +FleetPolicyAuthorization allows fleets to issue a signed policy artifact that constrains machine payments before operator authorization occurs. + +The effective payment policy therefore becomes the **intersection of fleet policy and operator policy**. + +``` +FleetPolicyAuthorization + ↓ +PolicyGrant + ↓ +SignedBudgetAuthorization + ↓ +SignedPaymentAuthorization + ↓ +SettlementIntent +``` + +The FleetPolicyAuthorization artifact defines constraints such as: + +- fleet-level spending caps +- approved service operators +- permitted payment rails +- permitted assets +- geographic restrictions + +During settlement verification, implementations MUST ensure that all MPCP artifacts remain compliant with the constraints imposed by the FleetPolicyAuthorization artifact. + +The full extension specification is defined in: + +`doc/Protocol/FleetPolicyAuthorization.md` + +# Future Extensions + +Possible extensions include: + +- fleet-level authorization hierarchies +- delegated policy authorities +- programmable payment intents +- zero-knowledge compliance proofs +- multi-chain settlement verification +- cross-operator interoperability + +--- + +# Conclusion + +The Machine Payment Control Protocol provides a framework for secure, policy-bounded autonomous payments. + +By structuring payments as a chain of cryptographically constrained authorizations, MPCP allows machines to transact independently while maintaining strong guarantees around spending limits, policy compliance, and settlement integrity. diff --git a/docs/reference/cli.md b/docs/reference/cli.md index c900162f..29709dfd 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -89,4 +89,4 @@ Golden test vectors are in `vectors/` for interoperability and regression testin - [Fleet Operator Tooling](../doc/architecture/FLEET_OPERATOR_TOOLING.md) - [Reference Profiles](../doc/architecture/REFERENCE_PROFILES.md) -- [Protocol: Verification](../protocol/verification.md) +- [Protocol: Verification](protocol/verification.md) diff --git a/docs/reference/sdk.md b/docs/reference/sdk.md index 1afe96a9..a08dedf8 100644 --- a/docs/reference/sdk.md +++ b/docs/reference/sdk.md @@ -140,4 +140,4 @@ const { valid, checks } = verifySettlementDetailed(context); - [Service API](service-api.md) — Higher-level facade - [Build a Machine Wallet](../guides/build-a-machine-wallet.md) -- [Protocol: Artifacts](../protocol/artifacts.md) +- [Protocol: Artifacts](protocol/artifacts.md) diff --git a/docs/scenarios/ev-charging.md b/docs/scenarios/ev-charging.md new file mode 100644 index 00000000..dc8450c8 --- /dev/null +++ b/docs/scenarios/ev-charging.md @@ -0,0 +1,27 @@ +# EV Charging Scenario + +MPCP for EV charging: variable session length, multiple kWh, charging operator destinations. + +## Scenario + +EV connects to a charging station. The station requests payment authorization. The vehicle (or charging session manager) evaluates policy and budget, signs an SPA for the charging session, and the station verifies the MPCP chain before supplying power. + +## Flow + +1. Vehicle (or fleet) obtains PolicyGrant + SBA with charging destinations +2. Charging station requests payment (amount may be estimated or updated during session) +3. Vehicle signs SPA for the authorized amount +4. Station verifies MPCP chain +5. Power is supplied; settlement executes when session ends + +## Characteristics + +- **Variable session length** — Amount may be estimated or adjusted +- **Multiple kWh** — Higher budgets than parking +- **Charging operator destinations** — Station/network-specific payment addresses + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Complete end-to-end scenario with actors, artifacts, timeline, and verification +- [Parking](parking.md) +- [Machine Commerce](machine-commerce.md) diff --git a/docs/scenarios/machine-commerce.md b/docs/scenarios/machine-commerce.md new file mode 100644 index 00000000..63d09889 --- /dev/null +++ b/docs/scenarios/machine-commerce.md @@ -0,0 +1,37 @@ +# Machine Commerce Scenario + +MPCP for autonomous machine-to-machine commerce: robots, vending, fleet payments. + +## Scenario + +A machine (robot, vending kiosk, delivery agent) pays for a service or product. The service requests payment. The machine evaluates policy and budget, signs an SPA, and the service verifies the MPCP chain before fulfilling. + +## Use Cases + +- **Vending machines** — Autonomous restock payments +- **Delivery robots** — Pay for charging, docking, access +- **Fleet vehicles** — Parking, charging, tolls (see [EV Charging](ev-charging.md) and [Parking](parking.md)) +- **IoT devices** — Pay for API access, resources +- **AI agents** — Bounded spending within policy + +## Flow + +1. Machine obtains PolicyGrant + SBA (from fleet or operator) +2. Service requests payment +3. Machine validates policy and budget +4. Machine signs SPA +5. Service verifies MPCP chain +6. Service fulfills; settlement executes + +## Characteristics + +- **Machine-initiated** — No human at payment time +- **Bounded** — Spending within pre-authorized envelope +- **Verifiable** — Service can independently validate authorization + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Full reference flow +- [EV Charging](ev-charging.md) +- [Parking](parking.md) +- [Fleet Payments](../guides/fleet-payments.md) diff --git a/docs/scenarios/parking.md b/docs/scenarios/parking.md new file mode 100644 index 00000000..48562acb --- /dev/null +++ b/docs/scenarios/parking.md @@ -0,0 +1,42 @@ +# Parking Scenario + +MPCP for parking: vehicle enters, pays on exit, offline-capable. + +## Scenario + +Vehicle parks at a meter or garage gate. The parking system requests payment. The vehicle evaluates fleet policy and session budget, signs an SPA, and returns the authorization. The parking system verifies the MPCP chain locally and opens the gate. + +## Flow + +1. Vehicle enters parking facility +2. PolicyGrant + SBA loaded (or issued at entry) +3. On exit, parking system requests payment +4. Vehicle signs SPA for session amount +5. Parking system verifies MPCP chain locally +6. Gate opens; settlement executes + +## Characteristics + +- **Offline-capable** — Underground garages may have no connectivity +- **Fixed or variable pricing** — Per-session or time-based +- **Local verification** — No central backend required at payment time + +## Run Example + +```bash +npm run build +npm run example:parking +``` + +Or: + +```bash +node examples/parking-session/generate.mjs +``` + +## See Also + +- [MPCP Reference Flow — EV Charging](../architecture/reference-flow.md) — Same authorization flow, different use case +- [EV Charging](ev-charging.md) +- [Machine Commerce](machine-commerce.md) +- [Offline Payments](../guides/fleet-payments.md#offline-flow) diff --git a/mkdocs.yml b/mkdocs.yml index 7f165ecb..ff8f10e7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,13 +35,36 @@ nav: - Quickstart: quickstart.md - Overview: - What is MPCP?: overview/what-is-mpcp.md - - The Problem: overview/problem.md + - Problem Statement: overview/problem-statement.md + - Design Goals: overview/design-goals.md - Comparison with Agent Protocols: overview/comparison-with-agent-protocols.md + - Architecture: + - Authorization Chain: architecture/authorization-chain.md + - System Model: architecture/system-model.md + - Actors: architecture/actors.md + - Artifact Lifecycle: architecture/artifact-lifecycle.md + - Reference Flow: architecture/reference-flow.md + - Implementation Roadmap: doc/architecture/MPCP_IMPLEMENTATION_ROADMAP.md - Protocol: - - Artifacts: protocol/artifacts.md + - MPCP Spec: protocol/mpcp.md + - Artifacts Overview: protocol/artifacts.md + - PolicyGrant: protocol/PolicyGrant.md + - SignedBudgetAuthorization: protocol/SignedBudgetAuthorization.md + - SignedPaymentAuthorization: protocol/SignedPaymentAuthorization.md + - SettlementIntent: protocol/SettlementIntent.md + - SettlementIntentHash: protocol/SettlementIntentHash.md + - FleetPolicyAuthorization: protocol/FleetPolicyAuthorization.md - Hashing: protocol/hashing.md - Verification: protocol/verification.md - Anchoring: protocol/anchoring.md + - Scenarios: + - EV Charging: scenarios/ev-charging.md + - Parking: scenarios/parking.md + - Machine Commerce: scenarios/machine-commerce.md + - Implementation: + - Verifier: implementation/verifier.md + - SDK: implementation/sdk.md + - Conformance: implementation/conformance.md - Guides: - Build a Machine Wallet: guides/build-a-machine-wallet.md - Fleet Payments: guides/fleet-payments.md