Skip to main content
Glama
RayanSDDS

open-mandate

by RayanSDDS

open-mandate

Version française

A signed permission slip an AI agent can show, and anyone can verify offline.

An agent asks: may I pay 149.90 EUR at hardware.example? open-mandate answers allow, needs_human, or deny — and says exactly which constraint failed. No account, no API call, no payment provider.

OK   149.90 EUR at hardware.example                   allow
OK   350.00 EUR -> human approval required          needs_human
OK   700.00 EUR -> over per-transaction cap         deny
OK   120.00 EUR at elsewhere.example -> merchant refused    deny
OK   receipt amount edited -> detected              false

Try it in 15 seconds

No install, no dependencies. Node 18+ is the only requirement.

git clone https://github.com/USER/open-mandate && cd open-mandate
npm run demo

18 assertions run and print ALL PASS. Nothing is downloaded — the crypto is Node's own node:crypto.

Related MCP server: vantic-mcp

Why it exists

AI agents are being handed spending power faster than anyone is defining the limits of that power. Today the answer is either "the human clicks confirm every single time" or "the agent has a card and we hope". There is no portable, inspectable object that says this agent, these merchants, this much, until this date, and above this amount ask me first.

That object is what this repository is.

It does not move money. It authorizes. Settlement stays wherever it already is — a card, a PSP, a bank transfer, a stablecoin rail.

What a mandate looks like

{
  "omv": "0.1",
  "id": "urn:uuid:25331759-d11d-491c-ba8d-f257e8163180",
  "issued_at": "2026-09-28T12:56:41.518Z",
  "expires_at": "2026-10-05T12:56:41.518Z",
  "principal": { "id": "did:key:MCowBQYDK2VwAyEA", "key": "<ed25519 spki>" },
  "agent":     { "id": "urn:agent:claude-desktop", "operator": "Anthropic",
                 "key": "<ed25519 spki>" },
  "grant": {
    "actions":   ["payment.authorize", "cart.create"],
    "merchants": ["hardware.example", "tools.example"],
    "purpose":   "Bathroom renovation supplies"
  },
  "limits": {
    "per_transaction": { "amount": "500.00",  "currency": "EUR" },
    "total":           { "amount": "1500.00", "currency": "EUR" },
    "max_uses": 10
  },
  "approval": { "human_above": { "amount": "200.00", "currency": "EUR" } },
  "sig": { "alg": "Ed25519", "kid": "...", "value": "..." }
}

Command line

mandate keygen  --out principal
mandate keygen  --out agent

mandate issue   --principal-key principal.key --agent-pub agent.pub \
                --agent-id urn:agent:claude-desktop --operator Anthropic \
                --actions payment.authorize,cart.create \
                --merchants hardware.example,tools.example \
                --per-tx 500.00 --total 1500.00 --human-above 200.00 \
                --out mandate.json

mandate inspect mandate.json
mandate check   mandate.json --action payment.authorize \
                --merchant hardware.example --amount 149.90 --ledger ledger.jsonl
mandate receipt mandate.json --agent-key agent.key --action payment.authorize \
                --merchant hardware.example --amount 149.90 --ledger ledger.jsonl
mandate audit   mandate.json --ledger ledger.jsonl

check exits 0 for allow, 10 for needs_human, 1 for deny — so it drops straight into a shell script or a CI gate.

Use it from any agent (MCP)

{
  "mcpServers": {
    "open-mandate": { "command": "node", "args": ["/path/to/open-mandate/mcp/server.js"] }
  }
}

Four tools: mandate_inspect, mandate_check, mandate_receipt, mandate_audit. Works with Claude Desktop, Claude Code, Codex, Cursor, VS Code — anything that speaks MCP.

Three decisions that make this different

1. Canonical JSON, not JSON.stringify. Keys are sorted recursively before signing (RFC 8785). A merchant can parse the mandate, re-serialize it, pass it through a queue, and the signature still verifies. Most hand-rolled implementations skip this and break the moment the document is touched.

2. The human approval threshold is enforced, not declared. human_above is not documentation. decide() returns needs_human and the caller cannot proceed. A limit nobody checks is decoration.

3. Receipts are hash-chained. Every action produces a receipt signed by the agent, committing to the hash of the previous one. Edit an amount, drop a line, reorder the file — audit catches it. An action with no receipt did not happen.

That third one came from watching a local model write "file verified" about a file it had never created. Agents claim. Receipts prove.

Where this sits next to Visa, Stripe and Google

Visa's Trusted Agent Protocol, Stripe's Shared Payment Tokens and Google's AP2 are all real, all published, and all solve the part open-mandate deliberately does not: moving the money. They are settlement-side.

open-mandate is the permission slip that can sit in front of any of them. It is worth using when you want:

open-mandate

Dependencies

none — node:crypto only

Verification

fully offline, no account with anyone

Settlement rail

none, by design — bring your own

Human approval threshold

first-class field, enforced by the verifier

Tamper-evident action log

hash-chained signed receipts

Money representation

decimal strings, integer arithmetic, never floats

No claim is made here about what those three protocols do or do not support — read their specs. The point is that this one is small enough to read in an afternoon and audit yourself.

See RELATED.md: Visa TAP, x402 and ATH, with licences and repository figures checked directly.

Status

Version 0.1, published for review. The schema will change based on feedback. Do not put real money behind it yet. There is no production deployment, no adopter, and no audit — if you see a claim otherwise anywhere, it is false.

Reviews of the threat model and the schema are the most useful thing you can contribute right now. Open an issue.

Tests

npm test

18 tests covering canonicalization, signature forgery, every limit, expiry, revocation, and five distinct receipt-tampering attacks.

License

Apache-2.0.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides cryptographic governance receipts for AI agents, enabling pre-execution evaluation and signed verdicts (EXECUTE/BLOCK/REVIEW/SHADOW) with offline-verifiable audit trails.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP hosts to verify agent spending mandates and receipts, providing stateless tools for authorization, chain verification, credential verification, and DID resolution.
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to propose wallet payments while a local, human-authored policy decides whether each transaction is approved, requires human confirmation, or is refused, and records every decision in a signed, append-only ledger.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides tools to evaluate an AI agent's step before execution, returning signed ALLOW/DENY receipts, and to verify receipt chain integrity.
    Apache 2.0