SignedBudgetAuthorization (SBA)
Artifact Type: MPCP:SBA
Part of the Machine Payment Control Protocol (MPCP).
Purpose
The SignedBudgetAuthorization (SBA) defines a signed spending envelope for a machine payment scope.
It is a protocol-level MPCP artifact that defines the spending envelope the Trust Gateway enforces for a session.
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 presented to the Trust Gateway, which verifies the SBA signature and enforces the budget ceiling before submitting each XRPL payment.
Policy linkage fields
grantId and policyHash are the canonical linkage from an SBA to its PolicyGrant. They are the
only PolicyGrant-origin fields required inside the SBA payload for binding to PA policy.
Deployments using gateway-only PolicyGrant presentation send the full PolicyGrant only to the Trust Gateway; merchants receive the SBA (which includes grantId and policyHash) without a copy of the grant. See Verification — Verification contexts.
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 |
| grantId | string | yes | References the PolicyGrant.grantId from which this budget was derived. Verifiers use this to resolve the grant and confirm policy chain linkage. |
| sessionId | string | yes | Session this budget applies to |
| actorId | string | yes | Actor identifier (vehicle, agent, robot, or any autonomous payment actor). When the PolicyGrant uses XRPL credential-based subject attestation (subjectCredentialIssuer / subjectCredentialType), actorId MUST be the agent's XRPL classic address (r...) — the same account that holds the on-chain credential — so verifiers can bind the SBA to the attested subject. See PolicyGrant — Subject Attestation. |
| scopeId | string | no | Optional scope identifier |
| policyHash | string | yes | SHA-256 hash of the canonical policy document under which this budget was authorized. Computed as SHA256("MPCP:Policy:<version>:" \|\| canonicalJson(policyDocument)). |
| currency | string | yes | Informational: the fiat reference currency from which this budget was derived (e.g. "USD"). Not used in verification arithmetic. |
| minorUnit | number | yes | Informational: decimal scale of the fiat reference currency (e.g. 2 for USD cents). Not used in verification arithmetic. |
| budgetScope | string | yes | SESSION | DAY | VEHICLE | FLEET | TRIP |
| maxAmountMinor | string | yes | Maximum authorized spend expressed in the on-chain asset's atomic units (e.g. drops for XRP). The session authority converts the fiat budget to on-chain units at SBA issuance time. |
| allowedRails | Rail[] | yes | Conforming SBAs: MUST be exactly ["xrpl"]. Must match the PolicyGrant rail set. |
| allowedAssets | Asset[] | yes | Permitted assets |
| destinationAllowlist | string[] | no | Optional allowed destination addresses |
| expiresAt | string | yes | ISO 8601 expiration timestamp |
SignedBudgetAuthorization (envelope)
| Field | Type | Required | Description |
|---|---|---|---|
| authorization | BudgetAuthorization | yes | The budget payload |
| issuer | string | conditional | Identifier for the signing entity (e.g. DID, domain, or vehicle:id.fleet.example). Required when the verifier uses Trust Bundle key resolution. Optional when the verifier resolves the key via MPCP_SBA_SIGNING_PUBLIC_KEY_PEM or HTTPS well-known. |
| issuerKeyId | string | yes | Identifies the specific key used to sign (alias: keyId retained for backward compatibility) |
| signature | string | yes | Base64-encoded signature over SHA256("MPCP:SBA:1.0:" |
Scope Model
SBA supports multiple budget scopes. All scopes are cumulative — maxAmountMinor represents the total authorized spending across all payments within the scope, regardless of how many individual payments are made.
| Scope | Meaning |
|---|---|
| SESSION | Budget applies to a single session |
| DAY | Budget applies across sessions for a calendar day |
| VEHICLE | Budget applies across sessions for a specific vehicle |
| FLEET | Budget applies across vehicles within a fleet authority |
| TRIP | Budget applies across sessions for a single multi-day trip or project (human-to-agent delegation) |
When present, scopeId identifies the entity the budget applies to.
Examples:
budgetScope: "SESSION"withscopeId= session identifierbudgetScope: "VEHICLE"withscopeId= vehicle identifierbudgetScope: "FLEET"withscopeId= fleet identifier
Budget and verification roles
Budget enforcement is split between roles. Merchant verifiers (offline acceptance) are stateless
per payment. The Trust Gateway is not stateless for the PA-signed budgetMinor ceiling —
it MUST maintain durable cumulative spend state and velocity counters (see Trust Model — Gateway durable spend state and PolicyGrant — Velocity limit enforcement).
| Role | Responsibility |
|---|---|
| Session authority (agent) | Tracks cumulative spending per scope. Presents SBAs within the remaining authorized envelope (maxAmountMinor). |
| Trust Gateway | Enforces PA-signed budgetMinor, authorizedGateway, velocityLimit, and optional gateway credentials; persists spend state across restarts. |
| Merchant verifier | Checks that the SBA maxAmountMinor does not exceed the PA-signed offlineMaxSinglePayment cap (offline mode only). |
Per-payment check at the gateway (in addition to durable budgetMinor tally):
currentPayment ≤ remainingAuthorizedEnvelope (from SBA and grant constraints)
Both values are in the on-chain asset's atomic units — the comparison is a direct numeric check with no currency conversion required. The session authority is responsible for converting the fiat budget into on-chain units at SBA issuance time, using the exchange rate and asset precision applicable at that moment.
Cumulative enforcement (session authority)
To align session-level totals with the gateway, callers MAY pass the running total of prior spending via cumulativeSpentMinor when invoking verifier helpers.
When provided, a stateless helper may apply:
cumulativeSpentMinor + currentPayment <= maxAmountMinor
instead of the bare single-payment check. This does not replace the gateway's durable budgetMinor
enforcement.
Session authority responsibility:
- MUST track cumulative spending per scope (SESSION, DAY, VEHICLE, FLEET)
- MAY pass cumulativeSpentMinor to verifier helpers for local checks
- MUST NOT present SBAs when cumulative spending would exceed maxAmountMinor
Offline trust assumption: In offline or air-gapped environments (e.g., vehicles without real-time connectivity), cumulative enforcement relies on the session authority (typically the vehicle wallet) maintaining the spending counter in trusted local storage. The verifier cannot independently verify the counter's accuracy in offline mode; this is an accepted trust assumption for offline deployments.
Example
{
"authorization": {
"version": "1.0",
"budgetId": "550e8400-e29b-41d4-a716-446655440000",
"grantId": "grant_abc123",
"sessionId": "sess_456",
"actorId": "ev-847",
"policyHash": "a1b2c3...",
"currency": "USD",
"minorUnit": 2,
"budgetScope": "SESSION",
"maxAmountMinor": "30000000",
"allowedRails": ["xrpl"],
"allowedAssets": [{ "kind": "IOU", "currency": "USDC", "issuer": "rIssuer..." }],
"destinationAllowlist": ["rDest..."],
"expiresAt": "2026-03-08T14:00:00Z"
},
"issuer": "did:web:fleet.example.com",
"issuerKeyId": "budget-auth-key-1",
"signature": "base64..."
}
Verification
All MPCP signatures MUST use domain-separated hashing before signing.
For SBA artifacts the domain prefix is:
MPCP:SBA:<version>:
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:
- Resolve the public key (as JWK) using one of the following, in order of precedence:
- Trust Bundle — if
trustBundlesare provided, look upissuerin the bundle'sissuerslist and retrieve the JWK byissuerKeyId. This path works fully offline. - Pre-configured key — if
MPCP_SBA_SIGNING_PUBLIC_KEY_PEMis set (or equivalent), use it directly. - HTTPS well-known — fetch
https://{issuerDomain}/.well-known/mpcp-keys.jsonand look up byissuerKeyId.
Then validate the signature over SHA256("MPCP:SBA: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 — except in SBA-only merchant context, where PolicyGrant subset checks are skipped because the grant is not available.
Relationship to Pipeline
PolicyGrant
↓
SignedBudgetAuthorization (SBA)
↓
Trust Gateway (verifies SBA + enforces budgetMinor ceiling)
↓
XRPL Settlement + Receipt
See Also
- MPCP Reference Flow — EV Charging — Demonstrates how SBA is used during runtime authorization.