Skip to content

Full Profile — SPA + IntentHash Binding

Part of the Machine Payment Control Protocol (MPCP).

Overview

The Full profile is an MPCP deployment configuration in which the intentHash field is required in the SignedPaymentAuthorization (SPA).

The intentHash is the SHA-256 hash of the canonical settlement intent payload, computed as:

intentHash = SHA256("MPCP:SettlementIntent:1.0:" || canonicalJson(canonicalPayload))

This binds the SPA to a specific, deterministic description of the settlement transaction. Mutation of any field in the canonical payload — destination, amount, asset, memo, or other fields — invalidates the authorization binding and causes verification to fail.


When to Use the Full Profile

The Full profile is appropriate when one or more of the following conditions apply:

Open Settlement Environments

Multiple vendors, operators, or intermediaries participate in the settlement pipeline. Without intentHash binding, a party in the middle could substitute or modify settlement instructions without invalidating the authorization.

Dispute-Sensitive Deployments

When payment disputes require cryptographic proof that the executed transaction matches the authorized intent, the intentHash provides an irrefutable binding between the SPA and the settlement. Combined with optional Intent Attestation Layer (IAL) anchoring, the commitment can be proven to have existed prior to settlement.

Multi-Vendor Infrastructure

A fleet operator, infrastructure operator, and payment service are distinct parties. Each stage of the pipeline is operated independently, increasing the surface area for substitution attacks. intentHash ensures that the settlement intent issued by one party cannot be modified by another.

Audit-Required Environments

Regulatory or contractual requirements demand a complete audit trail linking each payment authorization to the specific settlement transaction parameters, including fields beyond rail/asset/amount/destination.


Protection Provided

Check Protected
Rail Yes — SPA.rail checked against executed transaction
Asset Yes — SPA.asset checked against executed transaction
Amount Yes — SPA.amount checked against executed transaction
Destination Yes — SPA.destination checked against executed transaction
Memo / metadata Yes — included in canonical payload, mutation invalidates intentHash
Full payload mutation Yes — any deviation from the canonical intent fails verification

SPA Structure

A Full profile SPA includes intentHash:

{
  "authorization": {
    "version": "1.0",
    "decisionId": "dec_123",
    "sessionId": "sess_456",
    "policyHash": "a1b2c3...",
    "quoteId": "quote_789",
    "rail": "xrpl",
    "asset": { "kind": "IOU", "currency": "RLUSD", "issuer": "rIssuer..." },
    "amount": "19440000",
    "destination": "rDest...",
    "intentHash": "e3b0c44298fc1c149afbf4c8996fb924...",
    "expiresAt": "2026-03-08T14:00:00Z"
  },
  "issuer": "did:web:payments.example.com",
  "issuerKeyId": "payment-auth-key-1",
  "signature": "base64..."
}

Verification Behavior

Step 3 of the MPCP verification algorithm (intent binding) is executed when intentHash is present.

The verifier reconstructs the canonical payload from the settlement intent and confirms:

SHA256("MPCP:SettlementIntent:1.0:" || canonicalJson(canonicalPayload)) == SPA.intentHash

If the hashes do not match, verification fails and the settlement is rejected.


Optional: Intent Attestation Layer (IAL)

Full profile deployments may additionally publish the intentHash to the Intent Attestation Layer (IAL) before settlement execution. This creates a timestamped, tamper-evident public record that the commitment existed prior to the transaction, enabling third-party dispute resolution.

See Anchoring for the IAL integration specification.


Full Profile Security Requirements

PolicyGrant Signing

In Full Profile deployments, PolicyGrants MUST be signed by the policy authority. Configure MPCP_POLICY_GRANT_SIGNING_PUBLIC_KEY_PEM on the verifier; unsigned grants will be rejected.

policyHash Length

policyHash MUST be a full SHA-256 hash (64 lowercase hex characters), computed as:

policyHash = SHA256("MPCP:Policy:1.0:" || canonicalJson(policyDocument))

Short or truncated hashes are rejected in Full Profile deployments. The minimum accepted length is 12 hex characters; the full SHA-256 output (64 chars) is strongly recommended.

SPA Nonce

The nonce field SHOULD be present in Full Profile SPAs. The reference implementation auto-generates a UUID nonce on every createSignedPaymentAuthorization() call.

Recipients SHOULD record nonces to detect and reject replayed SPAs within the same session. The verifier itself does not track nonces (stateless model); nonce uniqueness enforcement is the responsibility of the session authority.


Offline Deployment

Full Profile deployments may operate offline for artifact signature verification. Trust Bundles pre-distribute the public keys of approved issuers, enabling PolicyGrant, SBA, and SPA signature verification without network access.

Connectivity still required for:

  • Revocation checksrevocationEndpoint cannot be called without network access. Offline verifiers accept the risk that a revoked grant remains valid until expiry. See Trust Bundles — Offline Verification.
  • IAL anchoring — Publishing or verifying intentHash commitments on Hedera HCS or XRPL requires connectivity to the respective network.

Deployments with strict revocation or anchoring requirements MUST ensure connectivity at verification time or use an embedded revocation list (planned future extension).

See Trust Bundles for the full specification.


See Also