Mandare
Official# Mandare
**Give your agents a budget they cannot talk their way out of.**
[](https://github.com/mandarelabs/mandare/actions/workflows/ci.yml)
[](LICENSING.md)
[](https://www.npmjs.com/package/@mandarelabs/sdk)
[](docs/SECURITY-REVIEW-S8.md)
Mandare is the accountability stack for AI agent fleets: signed agent
identity (**Passport**), signed machine-readable authority (**Mandate**), a
tamper-evident ledger of what agents actually did (**Ledger**), an offline
**kill switch** — and external **witnessing + public anchoring** so ledger
history cannot be truncated or rewritten without detection (with the witness
on separate infrastructure, not even by the operator — the solo compose
stack runs everything on one host and says so). Local-first: raw activity
never leaves your machine.

<sub>Replay of the captured [Demo 1](docs/demos/S2-runaway-demo.txt) run
(`pnpm demo`, the no-docker path; the docker quickstart stops at call #24) — the
same script CI executes and asserts on every push. Regenerate:
`node scripts/render-demo-gif.mjs`.</sub>
## Quickstart — 3 commands, no API keys needed
Needs Docker with Compose v2 (`up --wait` needs v2.1.1+). The images build
locally on first run, which takes a few minutes.
```bash
git clone https://github.com/mandarelabs/mandare && cd mandare
```
```bash
docker compose up -d --wait
```
```bash
docker compose run --rm demo
```
The demo releases a runaway agent loop against **your** gateway, priced
against a bundled mock provider: the enforcement is real, the money isn't.
The €20/day mandate kills it mid-run: 23 calls settle €19.17, call #24's reservation would
cross €20 and is refused `403 PER_DAY_EXCEEDED`, the refusal is itself a ledger entry, and
`mandare verify` proves chain VALID, counters == replay(ledger), and the
witnessed head history covers the chain. Dashboard at
**http://127.0.0.1:8788**. Real providers: put keys in `.env`
([docs](apps/docs/content/docs/quickstart.mdx)).
When you're done, `docker compose down -v` removes the containers and the
demo volumes (`mandare-data`, `mandare-witness-state`).
No docker (Node ≥ 22.13 and pnpm 10; if pnpm is missing, `install.sh` runs
`corepack enable`, a global change):
```bash
./install.sh
```
```bash
pnpm demo
```
(`pnpm demo` runs a cheaper model and raises the gateway's default 60
calls/minute velocity limit so the budget is the only limit in play: 71 calls,
call #72 refused at the same €20 cap. The docker demo above runs the stack's
real defaults.)
`pnpm demo` runs without a witness, so `mandare verify` there can't see
entries dropped from the end of the ledger — refusals included — unless you
pass a saved `--prev-head`. The docker stack runs a witness, and
`pnpm demo:witness` shows it catching exactly that.
Or from npm (CLI + MCP server, no checkout; the MCP server reads the ledger
at `MANDARE_LEDGER_DB`, default `./mandare-ledger.db`):
```bash
npm i -g @mandarelabs/cli && mandare help
```
```bash
npx -y @mandarelabs/mcp-server
```
Where state lands: the CLI's vault (`./mandare-vault.db`, used by `passport
issue` and `vault …`) keeps its master key in the OS keychain by default;
`passport issue` writes the agent's credential and key under
`~/.mandare/agents/` by default; and unless `MANDARE_VAULT=1`, the door's private key sits
next to the ledger (`<ledger>.doorkey.pem`, mode 0600).
## Proofs, not data
Raw prompts and responses never leave your machine. What crosses a trust
boundary is only ever a **proof**: salted tree heads to the witness, an
integrity certificate to an auditor, a revocation bitstring to a verifier.
```
agent (any SDK, base URL → the door)
│ RFC 9421-signed request (passport) or scoped PoP token
▼
┌──────────────── gateway door ────────────────┐
│ kill-check → policy (mandate: caps/window/ │ ┌─ witness (external) ─┐
│ scope/approval) → INTENT entry (reserves │────▶│ salted head history, │
│ cost in the ledger tx) → provider → RESULT │ acks│ consistency-enforced,│
│ entry (settles true cost) │◀────│ public anchor (OTS) │
└───────────────┬──────────────────────────────┘ └──────────────────────┘
▼
append-only ledger (SQLite/Postgres)
hash-chained · door-signed · RFC 6962 tree
budget counters + revocation = PROJECTIONS (replay-checkable)
▼
mandare verify · certify (third-party checkable) · dashboard · kill
```
Every door obeys three rules: **fail-closed on spend**, **log-before-act**,
and **agent input is hostile**. Refusals are ledger entries — the system keeps
its no's, and a witness keeps them from being quietly dropped.
## The five demos are the acceptance tests (CI runs all of them)
| # | Claim | Run |
|---|---|---|
| 1 | A runaway loop dies at €20, with proof | `pnpm demo` |
| 2 | A stolen token is dead paper; kill bites mid-task | `pnpm demo:dead-paper` |
| 3 | One signed mandate replaces 40 prompts; humans approve async | `pnpm demo:mandate` |
| 4 | The card declines AT THE NETWORK; one cap governs both rails | `pnpm demo:card` |
| 5 | Truncation and rewrites can't hide from an independent witness (verified with the door key held out-of-band) | `pnpm demo:witness` |
Each demo also exists as a self-contained, narrated scenario in
[`examples/`](examples/) — the story, the real captured output, and the code
to read next.
## Integrations
| Surface | Where | What |
|---|---|---|
| TypeScript SDK | `packages/sdk` (Apache-2.0) | A **signed fetch** for your existing Anthropic/OpenAI SDK (token PoP + passport RFC 9421) |
| Python client | `packages/sdk-py` (Apache-2.0) | Zero-dependency token-mode client (stdlib only) |
| MCP server | `packages/mcp-server` | The door as MCP tools: verify, budgets, issuance, kill — stdio, env-configured |
| OpenClaw skill | `integrations/openclaw` | Native AgentSkills skill (also works in Claude Code): budget awareness, honest refusals, proofs, kill |
| Self-host | `compose.yaml` + `install.sh` | gateway + witness + dashboard, no secrets needed for dry-run |
| Dashboard | `apps/dashboard` | Local-first fleet view over the ledger; zero telemetry |
| Docs | `apps/docs` → mandare.dev | Quickstart, concepts, threat model, reference |
## Security & provenance
- **Adversarially reviewed before launch — by AI, not yet by an external
auditor**: four parallel AI-assisted review passes (crypto/integrity ·
spend/enforcement · packaging/supply-chain · docs-vs-claims) were prompted
to break the system. 15 findings — 3 HIGH — all fixed with regression tests
or documented as accepted residuals, none silent. Full report:
[`docs/SECURITY-REVIEW-S8.md`](docs/SECURITY-REVIEW-S8.md), including what
was probed and held, the honest residuals, and the target list for the
external audit. A second AI-assisted audit pass (2026-09) found further
spend, witnessing and packaging defects; their fixes and red-team cases are
logged in `TASKS.md` (S10-fix 2A–2D). The external audit is still pending.
- **Fail-closed by construction**: no mandate → no spend; ledger down → no
action; witness dead → high-value actions refuse (the kill switch never
depends on anything remote).
- **Red-team suites run in CI** (rule R5): edit/delete/truncate/rollback/
replay/forge on SQLite AND Postgres, token theft + replay, signature
coverage attacks, webhook forgery, budget races, witness split-view — and
they may never be weakened to make a change pass.
- **Supply chain**: pnpm 10 with install scripts off, 3-day dependency
cooldown, frozen lockfiles, hand-rolled security primitives pinned to
official test vectors where they exist (RFC 6962 CT vectors, did:key/base58)
and otherwise tested against the published wire scheme with adversarial
round-trip suites (Stripe signatures, OpenTimestamps). From launch: npm
Trusted Publishing (OIDC provenance), cosign-signed images, signed skill
envelopes. Honest reproducibility bar in
[`REPRODUCING.md`](REPRODUCING.md).
- **Verify without trusting us**: the verifier, passport, and witness
protocol are Apache-2.0 and embeddable; `mandare certify` produces
integrity certificates a third party checks with no ledger access.
- Vulnerabilities: see [`SECURITY.md`](SECURITY.md) (private reporting, safe
harbor, 90-day disclosure).
## License
AGPL-3.0-only, **except** the embeddable packages listed in
[`LICENSING.md`](LICENSING.md) (spec, policy-engine, verifier, passport,
witness-protocol, sdk, sdk-py — Apache-2.0). The split is permanent; we do
not relicense.
TDQS
Scored across 8 tools
The three issue_* tools target clearly distinct artifacts (agent identity passport, spend mandate, session token), and the read-only tools split cleanly by target (ledger integrity, budget, gateway health). Minor potential overlap between mandare_verify and mandare_certify, since both concern ledger integrity, but their descriptions distinguish local verification from third-party disclosure certificates.
All tools share the mandare_ prefix and are largely verb-led (verify, issue_*, kill, certify), which reads predictably. Two names (budget_status, gateway_health) are noun phrases rather than verbs, a small deviation from the otherwise consistent verb pattern.
Eight tools is well-scoped for a delegated-authority gateway: identity issuance, mandate issuance, token minting, verification, budget inspection, revocation, certification, and health. Each tool earns its place with no obvious redundancy.
The issue/verify/budget/kill/certify lifecycle is mostly covered, but the kill description explicitly notes that reversal requires an operator-side 'reinstate' that has no MCP counterpart, and there is no tool to list or enumerate existing agents, mandates, or tokens. These are notable gaps an agent cannot work around from the tool surface alone.