Skip to content

Commit 8d8a3f8

Browse files
NAOR YUVALNAOR YUVAL
authored andcommitted
fix: PR23 guardrails polish - canonical names, SBA scope, deterministic timestamp, doc clarity
Made-with: Cursor
1 parent e8b3185 commit 8d8a3f8

4 files changed

Lines changed: 31 additions & 13 deletions

File tree

docs/examples/machine-wallet-guardrails.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Machine Wallet Guardrails Example
22

3-
Runnable example demonstrating MPCP as a **machine wallet guardrail layer**.
3+
Runnable example showing how MPCP acts as a **machine wallet guardrail layer**.
44

55
## Overview
66

@@ -12,6 +12,8 @@ A machine wallet should not send funds unless payment requests satisfy:
1212

1313
This example shows the integration pattern: check all three layers before signing.
1414

15+
This example focuses on wallet-side guardrail logic and uses a preloaded SBA-shaped authorization object rather than demonstrating full SBA issuance and signature verification.
16+
1517
## Run
1618

1719
```bash
@@ -27,14 +29,14 @@ node examples/machine-wallet-guardrails/wallet-integration.mjs
2729

2830
## What It Demonstrates
2931

30-
1. **Allowed request** — $15 to rParking passes all checks; SPA is signed
32+
1. **Allowed request** — $15 to rParking passes all checks; SignedPaymentAuthorization is created
3133
2. **Wrong destination** — $5 to rAttacker is rejected (not in allowlist)
3234
3. **Would exceed budget** — $20 to rCharging when session already spent $15 is rejected
3335

3436
## Guardrail Check Flow
3537

3638
```
37-
Payment request → PolicyGrant checkSBA checkSign SPA (or reject)
39+
Payment request → PolicyGrant validationSignedBudgetAuthorization validationSignedPaymentAuthorization creation (or reject)
3840
```
3941

4042
See [Machine Wallet Guardrails](../implementation/machine-wallet-guardrails.md) for the full guide and threat model.

docs/implementation/machine-wallet-guardrails.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ MPCP provides three layers of enforcement before a machine can pay:
3333

3434
- **Amount binding** — SPA commits to a specific amount and destination
3535
- **Intent hash** — SPA binds to a canonical SettlementIntent
36-
- **Tamper resistance**Settlement must match the signed authorization
36+
- **Tamper resistance**SettlementIntent and final settlement must match the signed authorization
3737

3838
## Wallet Integration
3939

@@ -44,15 +44,15 @@ A machine wallet integrates MPCP by performing checks *before* signing an SPA.
4444
```
4545
Payment request received
4646
47-
Check PolicyGrant (rail, asset, expiry)
47+
PolicyGrant validation (rail, asset, expiry)
4848
↓ PASS
49-
Check SBA (amount ≤ remaining, destination in allowlist, expiry)
49+
SignedBudgetAuthorization validation (amount ≤ remaining, destination in allowlist, expiry)
5050
↓ PASS
51-
Create SettlementIntent + SPA
51+
Create SettlementIntent + SignedPaymentAuthorization
5252
53-
Sign SPA
53+
SignedPaymentAuthorization creation (or reject)
5454
55-
Return SPA (and optional SettlementIntent) to payee
55+
Return SignedPaymentAuthorization (and optional SettlementIntent) to payee
5656
```
5757

5858
### Integration Checklist
@@ -65,7 +65,7 @@ Before signing an SPA, the wallet **must**:
6565
4. Use `createSignedPaymentAuthorization` with the policy decision and intent
6666
5. Never sign if any check fails
6767

68-
See the [wallet integration example](../examples/machine-wallet-guardrails.md) for a runnable implementation.
68+
See the [wallet integration example](../examples/machine-wallet-guardrails.md) for a runnable implementation. That example focuses on wallet-side guardrail logic and uses a preloaded SBA-shaped authorization object rather than demonstrating full SBA issuance and signature verification.
6969

7070
## Bounded Authorization
7171

examples/machine-wallet-guardrails/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Runnable example showing how a machine wallet integrates MPCP guardrails before
44

55
## Concept
66

7+
This example focuses on wallet-side guardrail logic and uses a preloaded SBA-shaped authorization object rather than demonstrating full SBA issuance and signature verification.
8+
79
A machine wallet should **not** send funds unless the payment request satisfies:
810

911
1. **PolicyGrant** — Rail, asset, expiration
@@ -26,7 +28,7 @@ npm run build
2628
node examples/machine-wallet-guardrails/wallet-integration.mjs
2729
```
2830

29-
## Full Flow Demo
31+
## Full Guardrail Flow Demo
3032

3133
For a complete narrative demo (policy → budget → SPA → verification → tamper detection), see:
3234

examples/machine-wallet-guardrails/wallet-integration.mjs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,21 @@ function checkGuardrails(policyGrant, sba, paymentRequest) {
5656
return { ok: false, reason: "policy expired" };
5757
}
5858

59-
// Layer 2: SBA
59+
// Layer 2: SBA (rail, asset, amount, destination, expiry)
60+
const sbaAllowedRails = new Set(sba.authorization.allowedRails ?? []);
61+
if (!sbaAllowedRails.has(rail)) {
62+
return { ok: false, reason: "rail not in budget authorization" };
63+
}
64+
const sbaAllowedAssets = sba.authorization.allowedAssets ?? [];
65+
const sbaAssetMatch = sbaAllowedAssets.some(
66+
(a) =>
67+
a.kind === asset?.kind &&
68+
a.currency === asset?.currency &&
69+
a.issuer === asset?.issuer
70+
);
71+
if (!sbaAssetMatch) {
72+
return { ok: false, reason: "asset not in budget authorization" };
73+
}
6074
const maxMinor = BigInt(sba.authorization.maxAmountMinor ?? "0");
6175
const reqMinor = BigInt(amount);
6276
if (reqMinor > maxMinor) {
@@ -95,7 +109,7 @@ async function handlePaymentRequest(policyGrant, sba, paymentRequest, sessionSpe
95109
amount: paymentRequest.amount,
96110
destination: paymentRequest.destination,
97111
asset: paymentRequest.asset,
98-
createdAt: new Date().toISOString().replace(/\.\d{3}Z$/, "Z"),
112+
createdAt: "2030-01-01T00:00:00Z",
99113
});
100114

101115
const paymentPolicyDecision = {

0 commit comments

Comments
 (0)