Skip to content

Commit c102148

Browse files
committed
deploy: b844c4d
1 parent 7d74c7c commit c102148

4 files changed

Lines changed: 218 additions & 2 deletions

File tree

spec/architecture/actors/index.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,7 @@ <h2 id="vehicle-wallet-machine-wallet">Vehicle Wallet (Machine Wallet)</h2>
21292129
<p>The wallet is the MPCP actor that signs SignedBudgetAuthorizations. Settlement is executed by the Trust Gateway.</p>
21302130
<blockquote>
21312131
<p><strong>Note on Actor Identity:</strong> The <code>actorId</code> field in SBA artifacts is self-reported by the wallet. Production deployments SHOULD establish actor attestation via device key binding (e.g., a hardware-backed key whose public key is registered with the fleet operator). Without attestation, <code>actorId</code> cannot be cryptographically verified and is informational only.</p>
2132+
<p><strong>Per-agent keys (SHOULD):</strong> Each vehicle or agent SHOULD have a unique SBA signing key. Shared keys prevent isolation of a compromised agent — revoking the shared key disrupts all agents using it. For XRPL deployments, the fleet operator SHOULD issue an XLS-70 Credential to each agent's account (<code>CredentialType = hex("mpcp:fleet-agent")</code>). The PolicyGrant can bind to the agent via <code>subjectCredentialIssuer</code> and <code>subjectCredentialType</code>. On compromise of one agent, the operator deletes that agent's credential — other agents are unaffected. See <a href="../../protocol/PolicyGrant/#subject-attestation">Subject Attestation</a>.</p>
21322133
</blockquote>
21332134
<h2 id="ai-agent">AI Agent</h2>
21342135
<p>An AI agent acting under human authorization, using MPCP to bound its spending authority.</p>
@@ -2178,7 +2179,8 @@ <h2 id="ai-agent">AI Agent</h2>
21782179
<p><strong>Examples:</strong> Travel booking agent, subscription manager, event budget agent.</p>
21792180
<blockquote>
21802181
<p>The <code>actorId</code> field in SBA artifacts is used for agent identity (e.g. <code>"ai-trip-planner-v2"</code>).
2181-
Agent attestation follows the same key binding recommendations as vehicle wallets.</p>
2182+
Agent attestation follows the same per-agent key and XRPL Credential recommendations as
2183+
vehicle wallets. See <a href="../../protocol/PolicyGrant/#subject-attestation">Subject Attestation</a>.</p>
21822184
</blockquote>
21832185
<h2 id="trust-gateway">Trust Gateway</h2>
21842186
<p>A mandatory online enforcement actor in MPCP's XRPL profile. The Trust Gateway holds the

spec/protocol/PolicyGrant/index.html

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,67 @@
16861686
</ul>
16871687
</nav>
16881688

1689+
</li>
1690+
1691+
<li class="md-nav__item">
1692+
<a href="#subject-attestation" class="md-nav__link">
1693+
<span class="md-ellipsis">
1694+
1695+
Subject Attestation
1696+
1697+
</span>
1698+
</a>
1699+
1700+
<nav class="md-nav" aria-label="Subject Attestation">
1701+
<ul class="md-nav__list">
1702+
1703+
<li class="md-nav__item">
1704+
<a href="#overview_2" class="md-nav__link">
1705+
<span class="md-ellipsis">
1706+
1707+
Overview
1708+
1709+
</span>
1710+
</a>
1711+
1712+
</li>
1713+
1714+
<li class="md-nav__item">
1715+
<a href="#per-agent-signing-keys-should" class="md-nav__link">
1716+
<span class="md-ellipsis">
1717+
1718+
Per-Agent Signing Keys (SHOULD)
1719+
1720+
</span>
1721+
</a>
1722+
1723+
</li>
1724+
1725+
<li class="md-nav__item">
1726+
<a href="#xrpl-credential-based-subject-attestation-should-for-xrpl-deployments" class="md-nav__link">
1727+
<span class="md-ellipsis">
1728+
1729+
XRPL Credential-Based Subject Attestation (SHOULD for XRPL deployments)
1730+
1731+
</span>
1732+
</a>
1733+
1734+
</li>
1735+
1736+
<li class="md-nav__item">
1737+
<a href="#error-code_1" class="md-nav__link">
1738+
<span class="md-ellipsis">
1739+
1740+
Error Code
1741+
1742+
</span>
1743+
</a>
1744+
1745+
</li>
1746+
1747+
</ul>
1748+
</nav>
1749+
16891750
</li>
16901751

16911752
<li class="md-nav__item">
@@ -2671,6 +2732,67 @@
26712732
</ul>
26722733
</nav>
26732734

2735+
</li>
2736+
2737+
<li class="md-nav__item">
2738+
<a href="#subject-attestation" class="md-nav__link">
2739+
<span class="md-ellipsis">
2740+
2741+
Subject Attestation
2742+
2743+
</span>
2744+
</a>
2745+
2746+
<nav class="md-nav" aria-label="Subject Attestation">
2747+
<ul class="md-nav__list">
2748+
2749+
<li class="md-nav__item">
2750+
<a href="#overview_2" class="md-nav__link">
2751+
<span class="md-ellipsis">
2752+
2753+
Overview
2754+
2755+
</span>
2756+
</a>
2757+
2758+
</li>
2759+
2760+
<li class="md-nav__item">
2761+
<a href="#per-agent-signing-keys-should" class="md-nav__link">
2762+
<span class="md-ellipsis">
2763+
2764+
Per-Agent Signing Keys (SHOULD)
2765+
2766+
</span>
2767+
</a>
2768+
2769+
</li>
2770+
2771+
<li class="md-nav__item">
2772+
<a href="#xrpl-credential-based-subject-attestation-should-for-xrpl-deployments" class="md-nav__link">
2773+
<span class="md-ellipsis">
2774+
2775+
XRPL Credential-Based Subject Attestation (SHOULD for XRPL deployments)
2776+
2777+
</span>
2778+
</a>
2779+
2780+
</li>
2781+
2782+
<li class="md-nav__item">
2783+
<a href="#error-code_1" class="md-nav__link">
2784+
<span class="md-ellipsis">
2785+
2786+
Error Code
2787+
2788+
</span>
2789+
</a>
2790+
2791+
</li>
2792+
2793+
</ul>
2794+
</nav>
2795+
26742796
</li>
26752797

26762798
<li class="md-nav__item">
@@ -2916,6 +3038,18 @@ <h3 id="policygrant-payload">PolicyGrant (payload)</h3>
29163038
<td>Hex-encoded credential type that approved merchants must hold (e.g. <code>hex("mpcp:approved-merchant")</code>). Used with <code>merchantCredentialIssuer</code>.</td>
29173039
</tr>
29183040
<tr>
3041+
<td>subjectCredentialIssuer</td>
3042+
<td>string</td>
3043+
<td>optional</td>
3044+
<td>XRPL address of the credential issuer that attests the subject's identity. When present, the gateway SHOULD verify on-chain that <code>subjectId</code>'s XRPL account holds a valid credential from this issuer. See <strong>Subject Attestation</strong> section below.</td>
3045+
</tr>
3046+
<tr>
3047+
<td>subjectCredentialType</td>
3048+
<td>string</td>
3049+
<td>optional</td>
3050+
<td>Hex-encoded credential type the subject must hold (e.g. <code>hex("mpcp:fleet-agent")</code>). Used with <code>subjectCredentialIssuer</code>.</td>
3051+
</tr>
3052+
<tr>
29193053
<td>offlineMaxSinglePayment</td>
29203054
<td>string</td>
29213055
<td>optional</td>
@@ -3324,6 +3458,73 @@ <h3 id="error-codes">Error Codes</h3>
33243458
</tbody>
33253459
</table>
33263460
<hr />
3461+
<h2 id="subject-attestation">Subject Attestation</h2>
3462+
<h3 id="overview_2">Overview</h3>
3463+
<p>The <code>subjectId</code> field identifies the entity receiving the grant (vehicle, agent, wallet). By
3464+
default, <code>subjectId</code> is self-reported and informational only — it cannot be cryptographically
3465+
verified. This means a compromised agent sharing a signing key with other agents can issue SBAs
3466+
that appear to come from any agent in the fleet.</p>
3467+
<p><strong>Problem:</strong> When multiple agents share the same SBA signing key, revoking a compromised
3468+
agent's grant affects all agents using that key. The fleet operator cannot isolate the
3469+
compromised agent without disrupting the entire fleet.</p>
3470+
<h3 id="per-agent-signing-keys-should">Per-Agent Signing Keys (SHOULD)</h3>
3471+
<p>Each agent or vehicle wallet SHOULD have a <strong>unique SBA signing key</strong>. This ensures:</p>
3472+
<ul>
3473+
<li>Revoking one agent's grant does not affect other agents</li>
3474+
<li>SBAs can be attributed to a specific agent for audit purposes</li>
3475+
<li>Compromised agents can be isolated without fleet-wide disruption</li>
3476+
</ul>
3477+
<p>Fleet operators SHOULD register each agent's public key in the Trust Bundle or JWKS endpoint
3478+
under a unique <code>kid</code> that includes the agent identity (e.g. <code>"sba-key:vehicle-1284"</code>).</p>
3479+
<h3 id="xrpl-credential-based-subject-attestation-should-for-xrpl-deployments">XRPL Credential-Based Subject Attestation (SHOULD for XRPL deployments)</h3>
3480+
<p>For XRPL deployments, the fleet operator or PA SHOULD issue an on-chain credential to each
3481+
agent's XRPL account using XLS-70 Credentials:</p>
3482+
<ul>
3483+
<li><code>Issuer</code> = Fleet operator's or PA's XRPL address</li>
3484+
<li><code>Subject</code> = Agent's XRPL account</li>
3485+
<li><code>CredentialType</code> = hex-encoded type (e.g. <code>hex("mpcp:fleet-agent")</code> or
3486+
<code>hex("mpcp:authorized-agent")</code>)</li>
3487+
</ul>
3488+
<p>The PolicyGrant binds to the specific agent via:</p>
3489+
<ul>
3490+
<li><code>subjectCredentialIssuer</code> — the XRPL address of the credential issuer</li>
3491+
<li><code>subjectCredentialType</code> — the hex-encoded credential type</li>
3492+
</ul>
3493+
<p><strong>Gateway enforcement (SHOULD):</strong> Before accepting SBAs from an agent, the gateway SHOULD
3494+
verify on-chain that the agent's account holds a valid, non-expired credential matching the
3495+
grant's <code>subjectCredentialIssuer</code> and <code>subjectCredentialType</code>:</p>
3496+
<div class="highlight"><pre><span></span><code>if PolicyGrant.subjectCredentialIssuer is present:
3497+
credential = lookupCredential(
3498+
subject: agent.xrplAddress,
3499+
issuer: PolicyGrant.subjectCredentialIssuer,
3500+
type: PolicyGrant.subjectCredentialType
3501+
)
3502+
if credential does not exist or is expired:
3503+
→ reject with SUBJECT_NOT_ATTESTED
3504+
</code></pre></div>
3505+
<p><strong>Isolation on compromise:</strong> When a single agent is compromised, the fleet operator:</p>
3506+
<ol>
3507+
<li>Deletes the agent's on-chain credential via <code>CredentialDelete</code></li>
3508+
<li>The gateway rejects further SBAs from that agent (credential check fails)</li>
3509+
<li>Other agents' credentials are unaffected — they continue operating normally</li>
3510+
<li>No grant reissuance needed for uncompromised agents</li>
3511+
</ol>
3512+
<h3 id="error-code_1">Error Code</h3>
3513+
<table>
3514+
<thead>
3515+
<tr>
3516+
<th>Code</th>
3517+
<th>Meaning</th>
3518+
</tr>
3519+
</thead>
3520+
<tbody>
3521+
<tr>
3522+
<td><code>SUBJECT_NOT_ATTESTED</code></td>
3523+
<td><code>subjectCredentialIssuer</code> is set but the agent does not hold a matching on-chain credential</td>
3524+
</tr>
3525+
</tbody>
3526+
</table>
3527+
<hr />
33273528
<h2 id="summary">Summary</h2>
33283529
<p>PolicyGrant establishes the <strong>policy boundary</strong> for machine payments.</p>
33293530
<p>It ensures that downstream SBA artifacts are always derived from a <strong>validated policy evaluation</strong>.</p>

spec/protocol/mpcp/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,15 @@ <h3 id="destination-forgery-agent-compromise">Destination Forgery (Agent Comprom
24312431
before settling. For deployments requiring dynamic merchant management, the PA can issue XRPL
24322432
Credentials (XLS-70) to approved merchants and reference them via <code>merchantCredentialIssuer</code>
24332433
and <code>merchantCredentialType</code> on the PolicyGrant. See <a href="../PolicyGrant/#destination-enforcement">PolicyGrant — Destination Enforcement</a>.</p>
2434+
<h3 id="agent-sba-signing-key-compromise">Agent SBA Signing Key Compromise</h3>
2435+
<p>If an agent's SBA signing key is compromised, the attacker can forge SBAs up to the remaining
2436+
budget. Exposure is bounded by the grant's <code>budgetMinor</code> and <code>expiresAt</code>. However, if multiple
2437+
agents share the same signing key, revoking the compromised key disrupts the entire fleet.</p>
2438+
<p><strong>Mitigations:</strong> Each agent SHOULD have a unique signing key. For XRPL deployments, the fleet
2439+
operator SHOULD issue an XLS-70 Credential to each agent's account. The PolicyGrant binds to
2440+
the agent via <code>subjectCredentialIssuer</code> and <code>subjectCredentialType</code>. On compromise, the
2441+
operator deletes that agent's credential — other agents are unaffected. See
2442+
<a href="../PolicyGrant/#subject-attestation">PolicyGrant — Subject Attestation</a>.</p>
24342443
<h3 id="cumulative-budget-overspend">Cumulative Budget Overspend</h3>
24352444
<p>The Trust Gateway is stateless and checks only that the current payment amount does not exceed <code>SBA.maxAmountMinor</code>. It does not track prior payments in the session.</p>
24362445
<p><strong>Session authority responsibility:</strong> The session authority MUST maintain a running total of amounts spent within the budget scope and MUST only issue new SBAs within the remaining authorized envelope.</p>
@@ -2710,6 +2719,10 @@ <h1 id="error-codes">Error Codes</h1>
27102719
<td><code>merchantCredentialIssuer</code> is set but destination does not hold a matching on-chain credential</td>
27112720
</tr>
27122721
<tr>
2722+
<td>SUBJECT_NOT_ATTESTED</td>
2723+
<td><code>subjectCredentialIssuer</code> is set but the agent does not hold a matching on-chain credential</td>
2724+
</tr>
2725+
<tr>
27132726
<td>SCOPE_UNSUPPORTED</td>
27142727
<td>Authorization scope is not supported by the verifier</td>
27152728
</tr>

spec/search/search_index.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)