← All docs

The agent wallet

Sanction is the wallet an AI agent carries into a world where most traffic is agents. MCP, A2A, and payment rails move work and money. None of them answer whether this agent is allowed to do this, under whose policy, with what remaining budget, and whether you can prove it. That object is the wallet.

Identity stays upstream. Sanction consumes it and mints governed runtime identity — never an identity of record. Payment rails stay rails. Sanction holds the mandate.


Three surfaces

SurfaceJobAnalog
CarryThe agent has the walletA card in a pocket, not a tool you remember to open
PresentThe agent shows a bounded mandateAn authorization, not the card number
VerifyThe counterparty checks itThe merchant-side auth

A human wallet is not a tool you invoke before coffee. The merchant checks the card. The network authorizes. An agent wallet has to work the same way, or it will not survive agents that do not share a prompt.


What is shipped

  • Carry (stdio). npx sanction-mcp in any MCP host. Ten tools. Cooperative: the host must ask before acting. Transport failure fails closed.
  • Carry (URL). https://getsanction.com/mcp — Streamable HTTP, agent API key (x-api-key or Authorization: Bearer pxy_...). Same ten tools. Cooperative. This is the paste for Claude / Cursor connectors.
  • Carry (approvals URL). https://getsanction.com/mcp/approvals — Streamable HTTP. OAuth for AI hosts (API-key also works). Eight tools. Cooperative. No execution-token issuance or vault credential retrieval. Full wallet /mcp and stdio stay API key; the broker stays agent-key.
  • Carry (broker). Register an upstream with POST /v1/broker/upstreams and point the host at /mcp/broker/<upstream>. INTERCEPTED: every tools/call runs the wallet's tool ladder BEFORE it is forwarded; tools/list is filtered through the same ladder so the host's picker does not see a tool policy would refuse. Empty allow-list stays opt-in (allow all except blocked). The upstream credential lives in the wallet's vault, never with the agent. Traffic that bypasses the broker is not governed; the plain wallet URL stays cooperative. Refusals include result._meta["sanction/decision"] with status and, action_type (tool.invoke or spend), and, when available, request_id, code, and reason. For a trusted synthetic upstream, hosts can use the bounded approval-loop example to poll and retry the identical call once with a valid grant. An unknown execution outcome requires reconciliation, not an automatic retry. Upstream JSON and SSE responses lose reserved sanction/ keys from protocol/result metadata before forwarding, including session-resume streams. Hosts must trust the configured broker connection, not markers copied from another source. This is not a signed decision receipt. Nonempty upstream responses must use application/json (up to 8 MiB) or text/event-stream (up to 1 MiB per frame); this also applies to x402 JSON challenges. Unsupported, malformed, or oversized bodies fail closed.
  • Present. POST /v1/exec mints a 15-minute HS256 JWT: credential scope, hard spend cap, wallet-bound, freeze-aware. This is a mandate. It was documented as credential injection. It is also how a parent agent hires a child, or how one agent proves authority to another.
  • Verify. POST /v1/mandate/verify — no API key. The JWT is the capability. Counterparties cannot check HS256 locally; they check it here. Frozen, revoked, expired, and garbage each have a named status. Invalid is HTTP 200 {valid:false} so agents fail closed on the body.
  • Discover. GET /.well-known/wallet-card.json — the issuer's card. Names carry (stdio + wallet URL + broker), present, verify, evidence, and the honesty contract (cooperative on stdio and the wallet URL; INTERCEPTED on the LLM gateway and on any MCP server fronted by the broker at /mcp/broker/<upstream>). GET /.well-known/mcp.json names both MCP profiles: approvals (/mcp/approvals, OAuth + API-key) and wallet (/mcp, API-key).

The decision engine, seats, cascade budgets, grants, vault, freeze, and tamper-evident export were already the wallet. These surfaces make it presentable.


What is Next

Find and connect inside the agent. OAuth for /mcp/approvals is shipped. Remaining work is tested host install paths, not building OAuth. Full wallet /mcp, stdio, and the broker stay API key. Registry metadata is not marketplace acceptance.

Per-agent Wallet Cards (this seat, this remaining budget band, never the key) attach to A2A Agent Cards so a peer can fetch constraints before a task.

Decision receipts — a hash-chained slip both parties keep after a governed action. AUDIT-1 is wallet-scoped export; A2A needs per-decision. The GTM object is one A2A demo: agent A mints a mandate; agent B verifies before working.


The year ahead

Agents will fetch, pay, invoke, and hire other agents as ordinary HTTP. Sites will 402 without a mandate the way they already 402 crawlers. MCP marketplaces will be untrusted the way npm is. Two agents from two orgs will meet over A2A and refuse to work without a live wallet.

Sanction's job in that world is not another protocol. It is the object those protocols present: carry, present, verify, evidence.


The next phase

Hosted remote MCP, broker mode, and OAuth for the approvals profile are shipped. Remaining work is verified host install (not building OAuth) and the A2A surfaces.

  1. Verified host install. OAuth for /mcp/approvals is live; full wallet /mcp, stdio, and the broker stay API key. Marketplace acceptance is not claimed.
  2. One A2A demo. Agent A mints a mandate; agent B verifies before working. That demo is the GTM object — not another MCP directory listing.
  3. Per-agent Wallet Cards attach to A2A Agent Cards. Directory listings follow the URL, not the stdio recipe.

Do not add an 11th cooperative tool. Do not invent an A2A competitor. Do not become an identity provider or a payment rail.


Honesty

stdio MCP and the hosted /mcp and /mcp/approvals URLs are agent-invoked. Skipping sanction_authorize* is possible — those surfaces stay cooperative. The LLM gateway and the MCP broker at /mcp/broker/<name> are interception: inference and tools/call are authorized before they are forwarded, and tools/list is filtered through the same ladder. Traffic that skips the broker or the gateway is not governed.