|
| 1 | +# Machine Wallet Guardrails |
| 2 | + |
| 3 | +MPCP acts as a **machine wallet guardrail layer**. A machine wallet should not send funds unless payment requests satisfy PolicyGrant constraints, SignedBudgetAuthorization session limits, and SignedPaymentAuthorization approval rules. |
| 4 | + |
| 5 | +This guide describes the guardrail model, how to integrate it into a machine wallet, and threat-model considerations. |
| 6 | + |
| 7 | +## The Guardrail Model |
| 8 | + |
| 9 | +MPCP provides three layers of enforcement before a machine can pay: |
| 10 | + |
| 11 | +| Layer | Artifact | Purpose | |
| 12 | +|-------|----------|---------| |
| 13 | +| 1 | PolicyGrant | Fleet-level constraints: allowed rails, assets, expiration | |
| 14 | +| 2 | SignedBudgetAuthorization (SBA) | Session spending envelope: max amount, destination allowlist | |
| 15 | +| 3 | SignedPaymentAuthorization (SPA) | Payment binding: specific amount, destination, intent hash | |
| 16 | + |
| 17 | +**Rule:** The wallet must not sign an SPA unless the requested payment passes all three checks. |
| 18 | + |
| 19 | +### Layer 1: PolicyGrant |
| 20 | + |
| 21 | +- **Rails** — Is the settlement rail (xrpl, evm, etc.) permitted? |
| 22 | +- **Assets** — Is the asset (e.g. RLUSD IOU) in the allowed set? |
| 23 | +- **Expiration** — Has the grant expired? |
| 24 | + |
| 25 | +### Layer 2: SignedBudgetAuthorization (SBA) |
| 26 | + |
| 27 | +- **Max amount** — Does the requested amount fit within `maxAmountMinor`? |
| 28 | +- **Destination** — Is the payee in `destinationAllowlist`? |
| 29 | +- **Cumulative spend** — For session budgets, has the session already spent up to the limit? |
| 30 | +- **Expiration** — Has the budget expired? |
| 31 | + |
| 32 | +### Layer 3: SignedPaymentAuthorization (SPA) |
| 33 | + |
| 34 | +- **Amount binding** — SPA commits to a specific amount and destination |
| 35 | +- **Intent hash** — SPA binds to a canonical SettlementIntent |
| 36 | +- **Tamper resistance** — Settlement must match the signed authorization |
| 37 | + |
| 38 | +## Wallet Integration |
| 39 | + |
| 40 | +A machine wallet integrates MPCP by performing checks *before* signing an SPA. |
| 41 | + |
| 42 | +### Decision Flow |
| 43 | + |
| 44 | +``` |
| 45 | +Payment request received |
| 46 | + ↓ |
| 47 | +Check PolicyGrant (rail, asset, expiry) |
| 48 | + ↓ PASS |
| 49 | +Check SBA (amount ≤ remaining, destination in allowlist, expiry) |
| 50 | + ↓ PASS |
| 51 | +Create SettlementIntent + SPA |
| 52 | + ↓ |
| 53 | +Sign SPA |
| 54 | + ↓ |
| 55 | +Return SPA (and optional SettlementIntent) to payee |
| 56 | +``` |
| 57 | + |
| 58 | +### Integration Checklist |
| 59 | + |
| 60 | +Before signing an SPA, the wallet **must**: |
| 61 | + |
| 62 | +1. Validate the payment request against the loaded PolicyGrant |
| 63 | +2. Validate against the loaded SBA (amount, destination, session balance) |
| 64 | +3. Create a canonical SettlementIntent for the requested payment |
| 65 | +4. Use `createSignedPaymentAuthorization` with the policy decision and intent |
| 66 | +5. Never sign if any check fails |
| 67 | + |
| 68 | +See the [wallet integration example](../examples/machine-wallet-guardrails.md) for a runnable implementation. |
| 69 | + |
| 70 | +## Bounded Authorization |
| 71 | + |
| 72 | +MPCP emphasizes **bounded authorization**: the machine is given a spending envelope, not open-ended access. |
| 73 | + |
| 74 | +- **Pre-authorized** — Policy and budget are set before the session |
| 75 | +- **Cryptographically enforced** — SBA and SPA are signed; tampering is detectable |
| 76 | +- **Local verification** — The verifier (e.g. parking meter) can validate the chain without calling a central API |
| 77 | + |
| 78 | +This makes MPCP attractive to fleet and robotics teams who need machines to spend money safely at scale. |
| 79 | + |
| 80 | +--- |
| 81 | + |
| 82 | +## Threat Model: Overspend and Misuse Prevention |
| 83 | + |
| 84 | +### Threat: Overspend |
| 85 | + |
| 86 | +**Scenario:** An attacker or bug causes the machine to pay more than authorized. |
| 87 | + |
| 88 | +**Mitigations:** |
| 89 | + |
| 90 | +| Mitigation | How MPCP Helps | |
| 91 | +|------------|----------------| |
| 92 | +| SBA max amount | SPA binds to a specific amount; settlement above SBA limit is invalid | |
| 93 | +| Session balance tracking | Wallet tracks cumulative spend; refuses SPA if would exceed budget | |
| 94 | +| Verifier checks | Verifier validates amount ≤ SBA maxAmountMinor | |
| 95 | +| Deterministic verification | `mpcp verify` fails if settlement does not match SPA | |
| 96 | + |
| 97 | +**Wallet responsibility:** Track session spend. Do not sign SPA if `requested amount + sessionSpent > maxAmountMinor`. |
| 98 | + |
| 99 | +### Threat: Wrong Destination |
| 100 | + |
| 101 | +**Scenario:** Funds are sent to an unauthorized recipient. |
| 102 | + |
| 103 | +**Mitigations:** |
| 104 | + |
| 105 | +| Mitigation | How MPCP Helps | |
| 106 | +|------------|----------------| |
| 107 | +| Destination allowlist | SBA `destinationAllowlist` constrains payees | |
| 108 | +| SPA binding | SPA commits to specific destination; cannot be redirected | |
| 109 | +| Verifier checks | Verifier validates destination in allowlist | |
| 110 | + |
| 111 | +**Wallet responsibility:** Reject payment requests whose destination is not in `destinationAllowlist`. |
| 112 | + |
| 113 | +### Threat: Unauthorized Rail or Asset |
| 114 | + |
| 115 | +**Scenario:** Machine pays on a disallowed rail or with a disallowed asset. |
| 116 | + |
| 117 | +**Mitigations:** |
| 118 | + |
| 119 | +| Mitigation | How MPCP Helps | |
| 120 | +|------------|----------------| |
| 121 | +| PolicyGrant | allowedRails, allowedAssets | |
| 122 | +| SBA | SBA must match policy | |
| 123 | +| Verifier | Validates rail and asset consistency across chain | |
| 124 | + |
| 125 | +**Wallet responsibility:** Reject requests for rails or assets not in PolicyGrant/SBA. |
| 126 | + |
| 127 | +### Threat: Replay and Tampering |
| 128 | + |
| 129 | +**Scenario:** Reuse of old SPA, or modification of settlement after signing. |
| 130 | + |
| 131 | +**Mitigations:** |
| 132 | + |
| 133 | +| Mitigation | How MPCP Helps | |
| 134 | +|------------|----------------| |
| 135 | +| Intent hash | SPA binds to canonical SettlementIntent; changed amount/destination invalidates hash | |
| 136 | +| Signatures | SBA and SPA are signed; tampering breaks verification | |
| 137 | +| Expiration | All artifacts have expiresAt; expired chain fails verify | |
| 138 | + |
| 139 | +**Wallet responsibility:** Never reuse an SPA. Create a fresh SPA per payment. |
| 140 | + |
| 141 | +### Threat: Key Compromise |
| 142 | + |
| 143 | +**Scenario:** SPA or SBA signing key is stolen. |
| 144 | + |
| 145 | +**Mitigations:** |
| 146 | + |
| 147 | +- SBA keys are typically held by fleet/issuer; compromise affects one fleet |
| 148 | +- SPA keys are per-machine; rotate if compromised |
| 149 | +- Budget limits (maxAmountMinor) bound maximum loss per session |
| 150 | +- Short session expirations reduce exposure window |
| 151 | + |
| 152 | +**Recommendation:** Use short-lived budgets for high-risk environments. Rotate SPA keys if compromise is suspected. |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## Summary |
| 157 | + |
| 158 | +- **Three-layer guardrail:** PolicyGrant → SBA → SPA |
| 159 | +- **Wallet rule:** Do not sign SPA unless all checks pass |
| 160 | +- **Threats addressed:** Overspend, wrong destination, wrong rail/asset, replay/tampering, key compromise |
| 161 | +- **Bounded authorization:** Pre-authorized limits, cryptographic enforcement, local verification |
0 commit comments