Vantic
A spending firewall and permission layer for AI agents. Give your agent a signed budget it can't exceed — even if it gets prompt-injected — and get a tamper-proof receipt for everything it does.
Zero dependencies · TypeScript · Ed25519 + W3C DIDs · works with MCP, LangChain, or any tool-calling agent.
The problem
Your AI agent can hold a wallet and call payment APIs. That's useful — and dangerous. One prompt injection from a poisoned web page, one hallucination, one bug, and your agent pays the wrong party. This is a documented, actively-exploited failure mode: agents tricked into wiring funds to attacker-controlled accounts.
What Vantic does
You issue your agent a signed mandate — a budget, a per-transaction cap, allowed actions, and an allowlist of who it may pay — and wrap its money-moving calls (purchase, subscribe, transfer, pay-per-use, payout, refund — any action that moves value). From then on, an out-of-scope payment is impossible: the check runs before the money-moving code, so even a fully compromised model can't execute it. Every allowed action emits a signed, tamper-proof receipt — a clean audit trail, and evidence if a charge is ever disputed.
Install
npm install @vantic/sdk
Protect your agent in ~5 lines
import { generateKeyPair, issueMandate, AgentWallet } from "@vantic/sdk";
const owner = generateKeyPair(); // you (the principal)
const agent = generateKeyPair(); // your autonomous agent
// Authorize the agent: what it may pay for, ≤ $200 each, ≤ $500/week, only these counterparties.
const mandate = issueMandate({
agent: agent.publicKey,
principal: owner.publicKey,
principalPrivateKeyPem: owner.privateKeyPem,
ttlSeconds: 7 * 24 * 3600,
scope: {
budget: { currency: "USD", amount: 50000, windowSeconds: 7 * 24 * 3600 }, // $500 / 7 days
maxPerTransaction: 20000, // $200
allowedActions: ["purchase", "subscribe"], // any money-moving action: transfer, payout, refund, …
allowedCounterparties: ["etsy.com", "*.shop.example"],
},
});
const wallet = new AgentWallet(mandate, agent.privateKeyPem);
// Your real payment call goes inside the executor. The guard runs FIRST;
// if the action is out of scope, the executor is never called.
await wallet.spend(
{ type: "purchase", counterparty: "etsy.com", amount: 4500, currency: "USD" },
async (action) => ({ outcome: "settled", result: await pay(action) }),
);
// A prompt-injected wallet.spend({ counterparty: "attacker.xyz", ... })
// throws GuardViolation — before any money moves.
Run npm run guard-demo to watch it block live attacker payments.
Already have a payment tool? Wrap it once.
For MCP / LangChain / function-calling agents, gate an existing tool without restructuring anything:
import { wrapMcpTool } from "@vantic/sdk";
const guardedPurchase = wrapMcpTool(purchaseTool, {
wallet,
toAction: (args) => ({ type: "purchase", counterparty: args.merchant, amount: args.amountCents, currency: args.currency }),
});
// Register `guardedPurchase` instead of `purchaseTool`. A blocked call comes back as a tool
// error the model can read and recover from; the real charge never fires.
Framework guides (OpenAI, LangChain, Vercel AI SDK, MCP, raw): docs/integrations.md.
What you get
- Hard spending limits — per-transaction cap and a rolling budget window, enforced deterministically.
- Counterparty allowlists — the agent can only pay who you allow (exact match or wildcard domains).
- Prompt-injection protection — the mandate is enforced outside the model, so a compromised agent can't spend out of scope.
- Tamper-proof receipts — a signed, hash-chained record of every action; verify offline; use as dispute evidence.
- Standard identity — agents and owners are W3C
did:key/did:webDIDs, and the owner→agent relationship is a W3C Verifiable Credential. - MCP server —
npx vantic-mcpexposes verification tools to any MCP host. - Zero dependencies — Node's built-in crypto only. Ed25519 + SHA-256.
How it works
Two primitives (full spec in spec/SPEC.md):
- Mandate — a signed statement from an owner authorizing an agent within a scope (budget, limits, counterparties, expiry, revocation).
- Receipt — a signed, hash-chained record binding each action to the mandate and its outcome. Tamper-evident.
Everything is deterministic and runs outside the agent's model.
Use it from an MCP host
npm run mcp # or, once published: npx vantic-mcp
Exposes stateless verification tools (no private keys): mandate_authorize, mandate_verify_chain, mandate_verify_credential, mandate_resolve_did.
Identity
Agents and owners can be identified by bare keys (key:<x>) or by W3C did:key DIDs — interchangeable, both verify. generateKeyPair() returns both. DIDs resolve to standard DID documents offline (resolveDidKey), the same key can be published as did:web (buildDidWebDocument), and the owner→agent relationship is a portable W3C Verifiable Credential (issueSponsorCredential / verifySponsorCredential). See npm run identity-demo.
Develop
cd sdk
npm install
npm test # 39 tests
npm run demo # end-to-end walkthrough
Learn more
- docs/integrations.md — add Vantic to OpenAI / LangChain / Vercel AI SDK / MCP / raw agents.
- docs/ap2-and-standards.md — how Vantic relates to AP2, x402, and the shared "mandate" concept.
- docs/agent-spending-security.md — securing agent spending (and why not to roll your own).
- spec/SPEC.md — the protocol.
Status & security
v0.1 — early, and honest about it. The code is production-quality (Ed25519 + SHA-256 + canonical JSON; did:key/did:web + Verifiable Credential identity; zero runtime dependencies), but it is not yet audited and the wire format isn't frozen.
ROADMAP.md— exactly what is and isn't hardened, and the path to v1.0.SECURITY.md— how to report a vulnerability (please don't open a public issue).spec/SPEC.md§8 — threat model and non-goals.
Feedback and PRs welcome. Apache-2.0.