▣ mandare

Quickstart

Three commands to a gateway that stops a runaway agent at a budget — no secrets required.

The 3-command path (docker)

No API keys needed: the stack ships a mock provider, so you see real enforcement (real mandate, real ledger, real witness) with zero setup.

git clone https://github.com/mandarelabs/mandare && cd mandare
docker compose up -d --wait
docker compose run --rm demo

The demo releases a runaway agent loop against your gateway. It will not stop on its own — the €20/day mandate stops it: 23 calls settle €19.17, then call #24's reservation would cross €20 and the loop dies with 403 PER_DAY_EXCEEDED. The refusal is itself a ledger entry, and mandare verify proves the chain is valid, the budget counters equal a fresh replay of the ledger, and the witnessed head history covers the whole chain.

Then open the dashboard: http://127.0.0.1:8788 — fleet view, spend per agent, the ledger trail, and a working kill button. Its witness badge is labeled SELF-ANCHORED: out of the box it checks the witness under the source the ledger file declares. Give the dashboard the door's public key out-of-band (MANDARE_DOOR_PUBLIC_KEY) to bind it — see Self-hosting.

What's running:

ServicePort (loopback only)Role
gateway8484The door: policy → ledger → provider
witness9411External head history (mock anchor by default)
dashboard8788Fleet view over the ledger
mock-provider—Stands in for Anthropic/OpenAI (no secrets)

Point it at real providers

Put real keys in .env (compose picks it up) and override the mock base URL:

cp .env.example .env
# in .env:
#   ANTHROPIC_API_KEY=sk-ant-...
#   ANTHROPIC_BASE_URL=https://api.anthropic.com
docker compose up -d --force-recreate gateway

Your agents keep their existing SDKs — point them at the door:

import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({ baseURL: 'http://127.0.0.1:8484' });

Every call is now metered against the mandate and recorded on the ledger.

Keys in .env behind an unauthenticated door are a starting point, not a boundary. Any process on the host that can read .env — including a hijacked agent — can take the provider key and call the provider directly, bypassing the mandate; and anything that can reach the door's port can spend through it. Before real agents run against real money, move provider keys into the vault and turn on token or passport auth — see Self-hosting.

For authenticated doors (scoped tokens / passports), see SDKs.

No docker: the solo installer

./install.sh
pnpm demo

install.sh checks Node ≥ 22.13, installs with a frozen lockfile (install scripts stay disabled — see Security), builds, and links ./bin/mandare. pnpm demo is the same runaway-loop acceptance test CI runs.

Issue a real mandate

The demo mandate is a generated dev artifact. The real flow takes two commands — the human signs once, the gateway enforces every call:

./bin/mandare passport issue --agent-name my-agent
./bin/mandare mandate issue --agent <did:key from above> \
  --per-tx 5 --per-day 20 --total 100 --approval-above 5 \
  --out mandate.sdjwt
MANDARE_MANDATE_PATH=mandate.sdjwt <restart the gateway>

passport issue writes the credential and the agent's private key (0600) to ~/.mandare/agents/ — outside your checkout, so a git add -A or a docker build can't pick the key up.

Everything else — vault-backed credentials, witness keys, card rail — is in Self-hosting.