The Proof Pair

Mandate in, receipt out — delegation made provable at both ends

Version: v0 (working draft) · Date: 2026-07-04 Status: Open working spec, CC-BY 4.0 (text) with a patent non-assertion commitment for implementations (covenant text accompanies this specification). Anyone may implement it. Canonical home + namespace: the-aios.org/proof-pair/ · rendered + announced at the-aios.com/standards/. Stability: nothing in v0 is stable — fields, vocabularies, and URIs may change without migration support until v1; implementers should pin to the dated draft they build against.


0 · Why this exists

Soon you'll be everywhere — and the only question left is whether it's really you.

Agents already act across organizational boundaries: they negotiate, book, file, pay. Every serious security framework now agrees on the foundation — without verifiable identity you cannot enforce access controls, maintain audit trails, or attribute actions to specific agents (Anthropic, Zero Trust for AI Agents, 2026). But identity alone only answers who. Delegation needs two more answers, one on each side of the act:

The Proof Pair is those two artifacts, specified together:

They are one specification, not two, because they share one invariant: every receipt references a mandate_id. The vocabulary an action is authorized in (the mandate's grant) is the vocabulary it is recorded in (the receipt's action). Verify the pair together and delegation becomes provable at both ends: mandate in, receipt out.

What this spec deliberately is: the schema and verification rules — open, portable, implementable by anyone on any DID/VC stack. What it deliberately is not: an implementation, a service, or a trust registry. Defensibility for any operator of these rails lives in what a schema cannot carry — occupying both ends of it (issuance at government grade; enforcement at the tool-call boundary of a running agent OS), and the jurisdictional anchoring and distribution earned around it. That is precisely why the schema can be fully open.

0.1 · Conventions

The key words MUST, MUST NOT, SHALL, SHOULD, SHOULD NOT, and MAY are to be interpreted as described in RFC 2119 / RFC 8174.

Terminology:

Term Meaning
Principal The human or organization on whose behalf an agent acts. Identified by a DID. The human root of trust is the principal DID at the top of every chain.
Agent An autonomous software actor holding its own DID and keypair, acting under a mandate.
Verifier Any party (portal, counterparty agent, service, auditor) that checks a mandate before honoring an action, or checks a receipt after one.
Deployment credential The prerequisite "birth certificate" credential binding an agent DID to its deployer/owner DID (out of scope here; profiled in the SovraID-for-Agents credential family). This spec assumes it exists.
Action A discrete, identifiable act an agent performs against a counterparty: a booking, a payment, a filing, a presentation, a message that commits its principal.

1 · Architecture in one picture

  PRINCIPAL (human DID — the root of trust)
      │  issues
      ▼
  MANDATE (VC: scoped · expiring · revocable · attenuate-only)
      │  held + presented by
      ▼
  AGENT (agent DID + keypair) ──── acts against ────▶ COUNTERPARTY
      │                                                   │ verifies mandate
      │  signs                                            │ BEFORE honoring
      ▼                                                   ▼
  RECEIPT (signed · hash-chained · owner-side · references mandate_id)
      │
      ▼
  RECEIPT CHAIN — verifiable by anyone, content-private by default

Authority flows down (principal → agent → sub-agent, attenuating at every hop). Attribution flows back up (receipt → mandate → agent → deployer → principal). The chain of who allowed this and the chain of who did this meet at the mandate_id.


2 · Part I — The Mandate credential

2.1 · Format

A mandate is a W3C Verifiable Credential in SD-JWT VC format (IETF draft-ietf-oauth-sd-jwt-vc), with key-binding (KB-JWT) to the agent holder and Ed25519 signatures as the baseline algorithm.

Deployment note (non-normative). SD-JWT VC is the only normative mandate format in v0 (resolved 2026-07-04). Rails that historically issued agent credentials as JSON-LD VCs with BBS+ selective disclosure can express the same claim set in that envelope as a legacy bridge, but such credentials are not conformant mandates; issuance should migrate to SD-JWT VC.

2.2 · Claims

Claim Type Req Semantics
iss DID MUST The issuing principal — a human or org DID. For a root mandate this is the human root of trust. For a delegated mandate this is the delegating agent's DID (§2.4).
sub DID MUST The agent DID receiving authority.
jti string MUST The mandate_id — globally unique. Every receipt references this value.
iat / nbf epoch s MUST Issued-at / not-before.
exp epoch s MUST Expiry. Short-lived by design — operator-set, hours-to-days for service mandates. Issuers MUST NOT default to long-lived mandates (the observed anti-pattern this spec kills: a hard-coded 365-day expiry on an authority credential).
cnf JWK/kid MUST Holder key confirmation (KB-JWT binding).
role string SHOULD The role the mandate authorizes (front-desk, bookkeeper, negotiator) — the human-legible summary of the grant set.
grants object MUST The scoped authority (§2.3).
preferences object MAY Preference claims — how to act within the grant ("within budget X, prefer Y"). Advisory to the agent, disclosable to counterparties; verifiers MUST NOT treat preferences as authority.
delegation object MUST if delegated Chain encoding (§2.4): parent_mandate_id, depth, max_depth.
status object MUST Revocation reference (§2.5).

2.3 · The grants object — scoped authority

"grants": {
  "service_actions": ["hotel.checkin.present_identity",
                       "hotel.checkin.present_reservation",
                       "hotel.checkin.receive_room_key"],
  "caps":            { "spend": { "amount": "0", "currency": "USD" },
                       "rate":  { "actions_per_day": 20 } },
  "data_domains":    ["identity.name", "identity.dateOfBirth",
                       "reservation.*"],
  "counterparty_policy": { "allow_did_methods": ["did:quarkid", "did:web"],
                            "require_credentials": ["OrganizationCredential"],
                            "allow": ["did:web:hotel.example"] },
  "escalation":      { "on_out_of_scope": "refer_to_principal",
                       "contact": "did:quarkid:sovra:<principal>" }
}

2.4 · Delegation — attenuate-only, N-level

Agents delegate to sub-agents by issuing child mandates. Rules:

  1. A child mandate's iss is the delegating agent's DID; its delegation.parent_mandate_id MUST reference the parent's jti; delegation.depth MUST equal parent depth + 1.
  2. Attenuation is mandatory and total: the child's service_actions MUST be a subset of the parent's; every cap MUST be ≤ the parent's; data_domains MUST be a subset; exp MUST be ≤ the parent's exp. A child mandate MUST NOT expand authority on any axis. (Rule adopted from the AIP capability-overlay discipline: overlays attenuate, never expand.)
  3. delegation.max_depth on the root mandate bounds the chain. A verifier MUST reject any mandate whose depth exceeds the root's declared max_depth. Root issuers SHOULD declare max_depth explicitly; RECOMMENDED value for production: 2 (principal → agent → sub-agent). Default when the root is silent: 1 (no sub-delegation) — conservative by default. Verifiers MAY enforce a stricter local ceiling. (Resolved 2026-07-04.)
  4. Verifiers MUST be able to walk the chain to the root: each parent mandate is either presented alongside the child or resolvable by mandate_id. The root's iss MUST be a principal DID (human or org) — every valid chain terminates at a human-or-institution root of trust. This termination rule is the single largest semantic difference between this spec and processor-anchored delegation schemes (Appendix A).
  5. Revoking a parent revokes the subtree: a verifier MUST treat a mandate as revoked if any ancestor is revoked or expired.

2.5 · Revocation

A mandate carries a status object referencing a revocation mechanism. Revocation MUST propagate in seconds-to-minutes, not CRL-hours — a compromised agent must be stoppable faster than it can act.

The layered model:

Layer-2 mechanism (resolved 2026-07-04). W3C Bitstring Status List is the single normative revocation mechanism in v0. Other registries (e.g. a private credentialStatus registry) MAY operate as conforming implementations whose entries validate against the same semantics — but interoperable verifiers are only REQUIRED to support Bitstring.

Status semantics (aligned with the production lifecycle): ACTIVE → SUSPENDED (reversible) → REVOKED (terminal). A SUSPENDED mandate MUST verify as not currently valid; verifiers MAY distinguish suspension from revocation in error reporting.

2.6 · Verification procedure (normative)

A verifier presented with a mandate for a proposed action MUST perform, in order:

  1. Format + signature. Parse the SD-JWT VC; resolve iss's DID document; verify the issuer signature.
  2. Holder binding. Verify the KB-JWT: signed by the key in cnf, over the verifier's fresh nonce and correct audience. Reject replays.
  3. Temporal validity. nbf ≤ now < exp.
  4. Status. Check the status mechanism (per §2.5). Reject SUSPENDED/REVOKED.
  5. Chain to root. If delegation is present, obtain and verify every ancestor (steps 1–4 each), enforce attenuation on every axis at every hop, enforce max_depth, and confirm the root iss is an acceptable principal DID (per the verifier's trust policy — e.g. trustedIssuers, an issuer registry, or a presented Deployment credential binding agent to owner).
  6. Scope. Confirm the proposed action's identifier ∈ grants.service_actions; confirm caps, data domains, and counterparty policy are satisfied.
  7. Decision. Any failure ⇒ reject with a proof-carrying error (which check failed, on what evidence). An out-of-scope action is rejected cryptographically demonstrably, not by policy prose.

A verifier MUST NOT honor authority implied by context, history, or deployment — authority is only what the mandate shows. (This kills the confused deputy: authority is presented per action or per session, never inherited.)

2.7 · Issuance + presentation transport (non-normative)

Mandates are transport-agnostic. Profiled bindings: OID4VCI for issuance, OID4VP (DCQL) for presentation to HTTP verifiers, DIDComm v2 present-proof for agent-to-agent and mailbox/mediator delivery (the headless-wallet path: authority on-device, delivery hosted). The protocol does not care that the holder wallet is headless.


3 · Part II — The Receipt

3.1 · What a receipt is

A receipt is a compact signed record (JWS, not a VC) produced by the agent after each mandated action. It binds action → agent → mandate into a hash chain that anyone can verify and no one can rewrite — while keeping the action's content private. (What the chain proves — and what it deliberately does not, such as completeness against an agent that silently declines to record — is stated plainly in Appendix C.)

Design properties:

Birth rule: receipts are born at service actions — discrete, high-stakes, low-volume acts (per §0.1's Action definition). Implementations MUST NOT require receipting of every message in a conversation; chat-level receipting is a scale decision outside v0.

3.2 · Structure

JWS payload (JSON, canonicalized per RFC 8785 before signing):

{
  "vct":              "https://the-aios.org/proof-pair/vct/receipt/v0",
  "receipt_id":       "urn:receipt:9f2c…",
  "seq":              42,
  "chain_id":         "room:!abc:matrix.the-aios.com",
  "prev_receipt_hash":"sha256:1b4e…",
  "action":           "hotel.checkin.receive_room_key",
  "action_hash":      "sha256:77d1…",
  "mandate_id":       "urn:mandate:5aa0…",
  "agent_did":        "did:quarkid:sovra:agent…",
  "counterparty_did": "did:web:hotel.example",
  "ts":               1783958400,
  "outcome":          "executed",
  "receipt_ref":      null
}
Field Req Semantics
receipt_id MUST Globally unique.
seq MUST Monotonic position in the chain, starting at 1.
chain_id MUST The chain scope — one chain per room / per counterparty relationship (e.g. a Forum room id). Chains are scoped so disclosure of one relationship's chain reveals nothing about others.
prev_receipt_hash MUST SHA-256 of the previous receipt's complete JWS. Genesis receipts (seq: 1) use the SHA-256 of chain_id.
action MUST The action identifier — the same namespaced string that appeared in the authorizing mandate's grants.service_actions. This is the pair's shared vocabulary.
action_hash MUST SHA-256 over the canonicalized action record (request + response material as the implementation profile defines). Both parties to the action can recompute it from their own copy; no one else learns the content.
mandate_id MUST The jti of the mandate under which the action was performed. The pair's junction.
agent_did MUST The acting agent.
counterparty_did MUST The other party to the action (or null for principal-internal acts — SHOULD be rare).
ts MUST Action timestamp (epoch s). MUST fall within the referenced mandate's validity window.
outcome SHOULD executed · rejected · escalated — rejections and escalations deserve receipts too; a refusal you can prove is half the trust story.
receipt_ref MAY Reference to an execution-verification receipt (e.g. a CommitLLM inference receipt) binding the action to the exact committed model that produced it. Optional; open-weight deployments only.

3.3 · Signing

3.4 · Chaining + verification procedure (normative)

To verify a receipt chain, a verifier MUST:

  1. Per-receipt signature. Resolve agent_did; verify each JWS.
  2. Chain integrity. For each receipt with seq n > 1: prev_receipt_hash equals SHA-256 of receipt n−1's JWS; seq increments by exactly 1; ts is non-decreasing. Genesis rule per §3.2.
  3. Mandate junction. Resolve mandate_id (presented alongside the chain, or resolvable): the mandate MUST verify per §2.6 as of ts (temporal containment: mandate.nbf ≤ ts < mandate.exp), and action MUST ∈ that mandate's grants.service_actions. A receipt whose action was outside its own mandate is a self-incriminating record — chain-valid but authority-invalid; verifiers MUST report the distinction.
  4. Content check (optional, bilateral). A party to the action MAY recompute action_hash from its own record and confirm equality — proving this specific content is what the chain attests, without third-party disclosure.

Handover. A principal (or their agent) MAY hand a chain — whole or a contiguous slice — to an auditor or counterparty. The chain verifies stand-alone: signatures, links, junctions, roots. This handover is the demo: the receipt chain, handed over, verified in front of you.

Gaps. A verifier can detect tampering and reordering, but absence of receipts (an agent that silently didn't record) is detectable only bilaterally — the counterparty holds its own copy of receipts for actions it witnessed. v0 makes no global-ordering or completeness claim beyond per-chain continuity. Checkpoint anchoring (resolved 2026-07-04): deferred to v0.1, with the path logged so implementers can plan for it: v0.1 will define an OPTIONAL periodic commitment of the chain-head hash to a public registry (ERC-8004 validation registry / SovraChain), upgrading completeness to publicly-provable. The addition is purely additive — a published hash — and requires no migration of v0 chains; it activates once the production L2 is live.

3.5 · Storage (non-normative)

The reference deployment stores chains owner-side (the principal's infrastructure or their hosted endpoint), one chain per room/relationship, with counterparties retaining their own copies of receipts they were party to. Hosted receipt-chain custody ("the vault" rail of an endpoint service) is an operational offering on top of this spec, not part of it — see the governance companion.


4 · Part III — The pair invariants (why this is one spec)

These invariants are the one-spec rule made normative. An implementation that satisfies Parts I and II separately but violates these is not a Proof Pair implementation:

  1. The junction. Every receipt MUST reference the authorizing mandate by mandate_id, and that mandate MUST be verifiable per §2.6 at the receipt's ts. No orphan receipts; no unaccounted authority.
  2. One vocabulary. The receipt's action value and the mandate's grants.service_actions entries are drawn from the same namespaced action vocabulary. Authorization and attribution speak one language; scope checks and audit queries are the same string match.
  3. Temporal containment. mandate.nbf ≤ receipt.ts < mandate.exp — no receipt outside its mandate's life.
  4. One key discipline. Mandate holder-binding keys and receipt-signing keys resolve from the same agent DID document. One identity, both directions.
  5. Root termination. Walking up from any receipt — receipt → mandate → (delegation chain) → root — MUST terminate at a principal DID: a human or institution. Attribution that terminates at a human is the category. ("Verifiable, owner-bound, revocable agent identity — that is the category.")

Together: mandate in, receipt out. Authority is proven before the act, attribution is provable after it, and the two proofs are one object viewed from both sides of the moment the action happens.


Appendix A · AP2 compilation — the cashable bridge

Google's Agent Payments Protocol (AP2) independently arrived at signed user-intent artifacts for agent commerce — Intent Mandates (what the user authorized the agent to seek) and Cart Mandates (the specific transaction approved). The naming convergence is strategic luck; the generalization is the claim: AP2 mandates are payment-scoped renderings of the general mandate this spec defines.

A.1 · Sovra Mandate → AP2 Intent Mandate

Proof Pair mandate AP2 Intent Mandate Notes
iss (principal DID) user identity (processor account) The delta (A.3): AP2's chain terminates at a processor account; ours at a DID with a verifiable human/institutional root.
sub + cnf (agent DID + key) agent identity AP2 assumes platform-attested agents; a Deployment credential is a portable upgrade.
grants.service_actions intent scope (what may be sought/purchased) Compile the payment-relevant subset; non-payment actions have no AP2 rendering.
grants.caps.spend spending limits Direct mapping.
exp mandate expiry Direct mapping.
preferences shopping preferences Direct mapping (AP2's context slot).
delegation (attenuate-only chain) No AP2 equivalent; sub-delegation collapses to the leaf agent at compilation.
status (revocation) mandate cancellation AP2 cancels within the processor; ours revokes at the credential layer, portably.

A Cart Mandate corresponds to a single-action, fully-attenuated leaf mandate (one action, exact amount, immediate expiry) — the degenerate case of §2.4.

A.2 · Receipts ↔︎ AP2 evidence

AP2's transaction records serve disputes inside the payment network. A Proof Pair receipt generalizes this: action_hash + mandate_id + chain position give network-independent, cryptographically portable evidence — the same dispute artifact whether the action was a payment, a filing, or a check-in. Where AP2 executes the payment, the receipt records it: action: "payments.ap2.cart.execute", action_hash over the Cart Mandate.

A.3 · The delta AP2 cannot express

AP2's trust chain terminates at a processor account — sufficient for charge disputes, silent on who the human behind the account is and on any action that isn't a payment. The Proof Pair chain terminates at a human root of trust — a DID whose holder can be verified against government-grade identity rails. For regulated, cross-institutional, or governmental delegation (an agent filing on behalf of a citizen), account-rooted authority is not enough. Compile down to AP2 for payments; keep the root for everything AP2 can't answer.

A.4 · OAuth/RAR rendering (the other gateway)

For OAuth-speaking services, a mandate SHOULD compile to RAR (RFC 9396) authorization_details: service_actionsactions, data_domainsdatatypes/locations, caps → custom fields, exp → token lifetime. Delegation chains render to RFC 8693 token-exchange chains. The mandate is the source of truth; RAR is one rendering; AP2 is another. The credential is the authority; gateway tokens are its shadows.


Appendix B · Standards strip

Standard Role in this spec
W3C DID + VC data model Identity + credential substrate; every actor is a DID.
SD-JWT VC (IETF) Mandate format: selective disclosure + KB-JWT holder binding.
OID4VC (OID4VCI / OID4VP) Issuance + presentation transports (headless holders are conformant holders).
DIDComm v2 Agent-to-agent + mailbox/mediator transport; present-proof binding.
ERC-8004 (Trustless Agents) Public anchor rails: agent DIDs registrable in the identity registry; chain checkpoints publishable to the validation registry (§3.4, if adopted).
AP2 Payment-scoped compilation target (Appendix A).
RAR RFC 9396 / RFC 8693 OAuth compilation target + verifiable delegation chains.
Bitstring Status List (W3C) Candidate normative revocation mechanism (§2.5).
RFC 8785 (JCS) Canonicalization for action_hash + receipt signing.
C2PA Pattern source for the receipt chain: signed, append-only manifest discipline, applied to actions.

Appendix C · Honest limits (state these; never oversell)

  1. Verification at presentation, not during execution. A mandate proves authorization; it does not prove the running agent still matches the authorized one mid-flight. Mitigations: short TTLs, session-bound presentations, attestation claims in the Deployment credential; receipt_ref closes the model-integrity slice for open-weight deployments. Full runtime drift detection is an industry open problem.
  2. Completeness is bilateral in v0. Missing receipts are detectable by counterparties, not by third parties (§3.4 gap; checkpoint anchoring would narrow it).
  3. Semantics of action_hash are profile-defined. The spec fixes that content is committed, not which bytes every implementation includes — implementation profiles MUST define their canonical action record.
  4. A mandate is authority, not judgment. Nothing here makes an agent act wisely inside its scope; it makes the scope provable and the acts attributable.
  5. Content-private is not metadata-private. chain_id, counterparty_did, action identifiers, and timestamps reveal who transacts with whom, when, and in what class of action — even with all content hashed. Chains are deliberately scoped per relationship to compartmentalize this; disclosure of a chain is itself a consented act; metadata-minimizing profiles are future work.
  6. Erasure vs append-only. Receipts referencing the agents of natural persons interact with data-protection erasure rights. By design, chains are per-relationship and owner-side — deleting a relationship's chain is deleting a file you hold, and counterparties retain only receipts of interactions they were party to. Cross-party erasure semantics are profile-defined; implementations targeting regulated deployments MUST define them.

Changelog


License. This specification's text is published under CC-BY 4.0, with a patent non-assertion commitment for implementations. Anyone may implement it; implementations, deployments, services, and trust registries built on it remain their owners' own.

Canonical home: https://the-aios.org/proof-pair/ · Maintained by the AIOS Guardian · the-aios.org · the-aios.com · sovra.io