Spend authorization, token budgets, and an encrypted credential vault for AI agents.
SaferSkills independently audited sanction (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The independent authorization plane for AI agents.
Before an agent spends money, invokes a tool, touches a credential, or provisions a resource, it asks Sanction. Sanction approves, escalates to a human, or denies. Every decision is logged and auditable. Sanction belongs to no platform: one policy engine answers across model providers, payment rails, identities, and agent ecosystems.
Connect Sanction to your agent, then ask it to call sanction_authorize_tool with require_approval: true and the exact proposed action. Approve or deny through the existing approval link or configured Slack channel. Approval gives that request an expiring, single-use grant; the agent must redeem it before acting. No policy edit is required, and blocked actions stay blocked.
Individuals can use Sanction free, without a card. The host must ask and honor the decision; connection alone does not enforce its other tools. Choose your host and try one approval.
departments become wallets in a tree; budgets, tool rules, and approval bands are enforced — not dashboarded — with chargeback-ready reporting underneath. Alerts tell you what happened; a decision happens first.
for clients carry a wallet wherever they execute: MCP hosts, Bedrock, your own stack via SDK or REST.
One policy decision engine governs every kind of agent action:
| Governed action | What Sanction enforces |
|---|---|
Spend (/authorize) | Auto-approve floor, human-escalation band, per-transaction hard cap, daily and monthly budgets — checked and debited atomically. |
Tools (/authorize/tool) | Block/allow/escalate lists for any MCP tool or external action. Escalations reach the approval inbox like spend does. |
Credentials (/exec + /mandate/verify + /credentials/inject) | AES-256-GCM envelope-encrypted vault (KMS-wrapped, rotating keys). Injection requires a scoped 15-minute mandate JWT and clearance ≥ the credential's bar. Counterparties verify the mandate with no API key. Every access audit-logged. |
Provisioning (/authorize/provision) | Seats, licenses, infrastructure — resource, line item, quantity, and dollars authorized in one call. |
Capability (/authorize/capability) | Skills, plugins, new APIs — acquiring capability is governed like spending money. One ordered rule list (block / allow / escalate, prefix-glob patterns) gates new power before it lands in an agent. |
What a decision looks like in practice — one POST /authorize with an amount, three possible outcomes, all of them terminal or resumable:
{ "status": "approved" }; budget counters debit in thesame transaction the decision persists (an advisory lock makes sibling agents queue, not race).
{ "status": "escalated", "request_id": "…" }; a humansees it in the approval inbox, and approving mints a one-use grant the agent redeems by retrying with grant_id. Policy decides what a timeout means (approve or deny) — nothing hangs forever.
"remediation": "Amount exceeds the per-transaction limit. Split into smaller charges or ask the owner to raise the limit." }. Codes are stable machine strings (DAILY_BUDGET_EXCEEDED, CATEGORY_BLOCKED, WALLET_FROZEN`, …) so agents branch and replan instead of parsing prose. Replays of the same request return the same code.
Around the engine:
(dashboard PWA, email, Slack). Approving mints a single-use, expiring grant the agent redeems on retry. Policy timeouts guarantee a terminal outcome.
holders, contractor auto-expiry (the key fails closed past the date), key rotation that keeps history, and batch creation from one template.
atomically so sibling agents can't race past a parent's limit. The console's spend view draws the month's runway — cumulative burn against the cap, pace, and the projected exhaust date — from wallet down to seat.
machines; and Slack two ways — a pasted incoming-webhook URL that deep-links to the decision, or Add to Slack, which installs per workspace over OAuth and posts interactive Approve / Deny buttons that run the same resolveApproval path as the dashboard, actor recorded. Each route subscribes to its own events. Guide
revision; every decision stores the revision in force and the exact context the engine evaluated. GET /authorize/{id}/evidence re-runs the pure rules over the stored context and proves the outcome reproduces.
POST /policy/simulate replays storeddecisions under a candidate policy — which calls flip, what spend wouldn't clear — before you change anything.
GET /audit-events merges every decision, token log,and secret access into one feed (CSV export included); GET /reporting/summary spans any period with day buckets and per-seat rollups; wallet stats project burn pace and exhaustion ETAs; a weekly digest lands in Slack every Monday.
GET /audit/export hands you a signed,hash-chained snapshot of your governed decisions: altering, dropping, or reordering any row breaks the chain, and the head is HMAC-signed by Sanction. A regulator or the governed customer runs POST /audit/verify — self-contained, no database — to prove nothing changed after signing, down to the first broken link.
as groups with agents as cards, each carrying a mandate stamp (live / paused / blocked). A wallet holds people, not just keys: team membership with roles (owner / admin / viewer), a switcher across every membership, and a viewer who can read everything and change nothing.
engine would have done while relaxing that wallet's own policy and caps. Ancestor subtree caps remain enforced and count observed spend; freeze and authentication checks still apply. Review would-be denials and their cost, then flip each pool to enforce in one confirm-gated click.
POST /outcomes) and awallet over its cost-per-outcome ceiling throttles to human-gated spend. Wallets can be frozen outright, and budget reallocated across the tree.
https://getsanction.com/api/gateway/<provider> with x-sanction-key — usage is metered and budget-capped with zero per-call instrumentation.
Every security claim above maps to enforcing code and a regression test in docs/TRACEABILITY.md — 1,100+ tests behind a coverage gate of 90% statements/lines, 94% functions, and 83% branches, including concurrency and Postgres row-level-security suites.
Eleven installable policy packs cover the common shapes — Startup defaults, Coding agent seat, MCP tool governance, Compliance baseline, Client-safe launch, and No-egress (Sanction Local) among them. GET /policy/packs lists them; POST /policy/packs/{id}/preview simulates one against your last 30 days of real decisions before anything changes; apply writes it as a policy revision.
Policy edits are never a leap of faith:
POST /policy/simulate replays your stored decision history under thecandidate — see exactly which calls flip and what spend wouldn't clear.
records the revision in force.
GET /authorize/{id}/evidence re-runsthe rules over the stored context and proves the outcome reproduces.
Use Sanction's vault when credentials should flow through the same policy, approval, and audit trail as spend and tools — one clearance model, no separate secrets cluster. Keep your existing Vault or Secrets Manager when you need fleet-scale secret lifecycle management independent of agent governance; Sanction consumes upstream identity and secrets rather than replacing them. Threat model: docs/SECURITY.md.
Platform vendors govern agents inside their own walls. Sanction authorizes agents wherever they run. Pick the shortest path to your stack:
| You want to… | Use | First step |
|---|---|---|
| Govern any MCP host (Claude Desktop, Cursor, …) | MCP wallet | Paste https://getsanction.com/mcp or npx sanction-mcp |
| Intercept tools/call and filter tools/list on an MCP server | MCP broker | Register the upstream, point the host at /mcp/broker/<name> |
| Meter model spend with zero code changes | LLM gateway | Point the SDK base URL at /api/gateway/<provider> |
| Govern agents in a TypeScript app | SDK | npm install sanction-sdk |
| Call the engine from anything else | REST API | POST /v1/authorize with an x-api-key |
| Plug into an AuthZEN enforcement point | PDP | Point it at /api/access/v1/evaluation |
| Orchestrate on AWS Bedrock | Action Group | docs/BEDROCK.md |
The full menu:
https://getsanction.com/mcp (Streamable HTTP, x-api-key) or npx sanction-mcp in any MCP host. The agent carries the wallet. Wallet Card · guidenpm install sanction-sdk (source): SanctionClient (agent plane) and SanctionAdminClient (management plane), plus framework adapters (SanctionMiddleware, sanctionTool)/api/openapi.json (Bedrock-compatible)Fastest first decision: bash examples/setup.sh — wallet, agent, and a demo policy in one command, printing the env exports your agent needs (examples/ has runnable clients to point at it).
Agent wallet · Quickstart · Starter kit · LangChain · CrewAI · Vercel AI SDK · Bedrock Agents · Agent fleets · AuthZEN PDP · Multi-tenant runbook · Notifications
Base URL: https://getsanction.com/api/v1 — grouped by workflow. Agent endpoints take x-api-key pxy_…; management endpoints take the owner's x-mgmt-key sk_….
Ask permission — the data plane an agent calls:
POST /authorize — Authorize a spend action (grant_id redeems an approval)
POST /authorize/quote — Authorize an x402 payment challenge before the wallet signs
POST /authorize/tool — Authorize a tool invocation
POST /authorize/provision — Authorize provisioning (resource + line item + $)
POST /authorize/capability — Authorize acquiring capability (skill/plugin/API)
GET /authorize/{id} — Poll an escalated decision (grant receipt included)
POST /tokens — Log LLM token consumption against the daily budget
POST /outcomes — Report an outcome; spend becomes answerable to resultsEscalate to a human — over the line, someone decides:
GET/POST /approvals — The approval inbox; approving mints a one-use grantCarry credentials — scoped mandates instead of raw secrets:
POST /exec — Mint a scoped mandate JWT (15-min TTL)
POST /mandate/verify — Counterparty checks a presented mandate (no API key)
POST /credentials/inject — Inject a decrypted credential (Bearer JWT)
POST /credentials/vault — Store an encrypted credential (owner)
POST /exec/revoke — Kill a live execution token (owner)Prove what happened — audit, evidence, reporting:
GET /authorize/{id}/evidence — Audit proof: re-run the pure rules over the stored
context and confirm the recorded outcome reproduces
GET /audit-events — Unified audit feed (decisions, tokens, secret access; ?format=csv)
GET /reporting/summary — Any range ≤92 days: totals, day buckets, per-agent
GET /reporting/daily-summary — One-day rollup
GET /audit/export — Signed, hash-chained decision export (owner; ?download=1)
POST /audit/verify — Verify a tamper-evident export (recompute chain + signature)Shape policy — edit safely, prove impact first (owner):
GET/PATCH /wallets/policy — Read / update budgets, thresholds, lists, capability rules
POST /policy/simulate — Replay real history under a candidate policy (what-if)
GET /policy/packs — List installable policy packs (public)
POST /policy/packs/{id}/preview — Simulate a pack against your last 30 days
POST /policy/packs/{id}/apply — Install a pack as the wallet policy (writes a revision)Run the fleet — wallets, seats, keys (owner):
POST /wallets — Create a wallet + policy (management key shown once)
GET /wallets/stats — Today + month-to-date stats + burn projections
GET /wallets/tree — Subtree spend rollup
POST /wallets/keys/rotate — Rotate the wallet's data-encryption key
POST /agents — Register a seat (holder, expiry; key shown once)
POST /agents/batch — Stamp one template across up to 50 seats
GET/PATCH /agents — List / per-seat budgets, clearance, holder, expiry
POST /agents/rotate — Rotate a seat's key (optionally pass to a new holder)
POST /webhooks — Register a notification route (per-event subscriptions)
POST/GET/DELETE /broker/upstreams — Register the MCP servers the broker may front (BROKER-1)
POST /wallets/freeze — Pause every agent action in this wallet and its subtree
POST /wallets/unfreeze — Resume exactly where the fleet stopped
POST /wallets/reallocate — Move budget across the wallet tree
POST /wallets/bootstrap-key — Mint a management key for a legacy wallet
GET /outcomes — Reported outcomes + cost-per-outcome state
GET /activity — Recent decision activity for the consoleSpeak the standard — AuthZEN PDP + AARP (agent key; base https://getsanction.com/api — spec-canonical paths):
POST /access/v1/evaluation — OpenID AuthZEN 1.0 evaluation (decision-only)
POST /access/v1/evaluations — AuthZEN batch, all three evaluation semantics
POST /access/v1/access-request — AARP: open an escalation from a signed binding token
GET /access/v1/access-request/{id} — AARP task status (maps to the profile's states)Full schemas: /api/openapi.json.
The agent carries a Sanction wallet. Discovery: GET /.well-known/wallet-card.json. stdio MCP is cooperative — the host must ask before acting. Cursor plugin (MCP + skills): cursor-plugin/.
{
"mcpServers": {
"sanction": {
"command": "npx",
"args": ["sanction-mcp"],
"env": {
"SANCTION_API_URL": "https://getsanction.com/api/v1",
"SANCTION_API_KEY": "pxy_..."
}
}
}
}Next.js 16 (App Router) + TypeScript · Prisma 7 on Neon Postgres (row-level security enforced at the database) · Vercel · jose (HS256, alg-pinned) · AES-256-GCM envelope encryption with AWS KMS root of trust in production.
CONTRIBUTING.md gets you from clone to green PR (npm install && npm run check — no database needed for unit tests). Security model and disclosure: docs/SECURITY.md. Vocabulary: docs/DOMAIN.md.
It's free, or it's an agreement. Free for individuals — no card, personal and production use. Beyond that, an enterprise agreement shaped to your deployment: SSO, policy administration, audit export, SLA. Talk to us.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.