Releases: ericlovold/sanction
Release list
v0.9.0
v0.8.0 made the wallet a thing you could paste, hand over, and verify.
v0.9.0 is the enforcement release: on governed paths, the engine no longer
depends on the agent's cooperation.
Interception
The MCP broker fronts any upstream MCP server. Register the upstream on your
wallet, point your host at /mcp/broker/<upstream>, and every tools/call
is authorized before a byte reaches the upstream — inheritance,
conditional rules, observe mode, evidence, escalation, all of it. The
upstream's credential stays vaulted server-side and is injected on the
forward, so the agent never holds it — and the broker never copies inbound
headers upstream, so your Sanction key can't leak either.
A refused call returns a proper MCP result with a machine code and
remediation. An escalation names its request_id; approval mints a one-use
grant the agent redeems by retrying with _meta["sanction/grant_id"].
The x402 spend gate
Stablecoin settlement is irreversible — the moment between receiving a
payment challenge and signing it is the only control point there is.
Sanction now takes that moment.
POST /v1/authorize/quoteprices an x402402challenge and runs it
through the same ladder as any purchase: budgets, escalation bands,
cascade caps, evidence, the decision meter.- Through the broker this is interception, not cooperation: when a fronted
upstream answers 402, anything but an approval means the challenge is
withheld — an agent that never receives payment requirements cannot
sign them. - Two rules keep it honest: no oracle, no FX (USD-pegged stablecoins
with known decimals only; anything else denies asQUOTE_NOT_PRICEABLE
rather than guessing) and worst case wins (a challenge offering
several ways to pay is authorized at its most expensive option).
Still non-custodial and veto-only: Sanction holds no keys and signs
nothing. It decides whether the demand is allowed to reach your wallet.
Rules that inherit, and rules that read the clock
- Tool and capability rules now cascade down the wallet tree. A child
may tighten, never loosen: block it at the org root and no team below
can allow it back. Every decision records which layer decided. - Rules can carry conditions.
outside_hours_utcescalates deploys
after hours;after_model_calls_todayis the runaway breaker — past N
model calls today, matching tools block until a human looks. Signals are
snapshotted into evidence, so replay reads the record, never the live
clock.
Approvals where your team already is
Sanction for Slack is live. Add to Slack binds a workspace and channel
to your wallet over OAuth, the bot token lands in the wallet's encrypted
vault, and interactive Approve / Deny cards resolve through the same
grant-minting path as the dashboard — actor recorded, audit intact.
Metering, honestly
Every wallet now counts decisions per month — approve, escalate, and deny
each count once; idempotent replays and simulations never do. No fee
attaches to it. The unit is measured honestly long before anything is
priced in it.
Also in this release
npm install sanction-sdk— the TypeScript SDK, zero runtime
dependencies, with the full escalate → poll → grant retry loop and
Vercel AI SDK adapter.- All 16 open dependency advisories cleared (
npm audit: 0), including
Next.js SSRF and cache-confusion fixes; automated weekly dependency PRs
now stand guard. - The official MCP registry listing is current again.
- A new guide on composing Sanction with Vercel Connect: authorize the
capability, then mint the token.
Honest boundaries
Interception holds for traffic through the broker and the LLM gateway.
The plain hosted wallet URL and stdio MCP remain cooperative — the host
must ask. Traffic that goes straight to an upstream is not governed, and
the Wallet Card says so.
Install: npx sanction-mcp · npm install sanction-sdk ·
getsanction.com · /slack
v0.8.0 — a wallet you can paste, hand over, and verify
Where v0.7.0 made governance adoptable, v0.8.0 makes the wallet a thing you can paste, hand over, and verify.
Paste it
The wallet is a URL. https://getsanction.com/mcp speaks Streamable HTTP and authenticates with the agent key, so Cursor and Claude connectors take a URL and a header instead of a JSON blob — the same ten tools as npx sanction-mcp. A browser GET returns a paste page rather than a raw 401. sanction-mcp is conformant with the MCP 2026-07-28 revision and forwards W3C trace context, so a governed decision correlates with the agent run that requested it.
Boundary, stated plainly: stdio and the hosted URL are both cooperative — the host must ask before acting. Broker interception of tools/call is Next, and we don't claim it today.
Verify it
GET /.well-known/wallet-card.json is how a counterparty discovers what a wallet carries. POST /v1/mandate/verify lets them check a presented execution mandate with no Sanction API key — frozen, revoked, expired, or garbage, each named, and invalid answers HTTP 200 so agents fail closed on the body.
Hand it over
Wallets now have people: team membership with roles, a wallet switcher that reaches every membership, and a viewer role that genuinely cannot mutate. An org owner decides escalations anywhere in their subtree.
Approvals reach you where you already are — Add to Slack installs per workspace over OAuth and posts interactive Approve / Deny cards that run the same resolveApproval path as the dashboard, with the actor recorded.
See it
The console leads with a roster — the wallet tree as groups, agents as cards, a mandate stamp on each — and the rail is three items instead of thirteen. Month runway draws cumulative burn against the monthly cap with the projected exhaust date. Seat health flags the seats whose denial rate is hot or climbing, each with the decision code it keeps hitting. Providers are connected once: keys land in the vault and inject at the gateway.
One money fix worth naming
Gateway metering no longer fails open to $0 for a model missing from the price table — unknown models bill at the table-max fallback rate with a warning. Under-metering is a budget hole, so it now errs expensive.
Also in this release
Eleven policy packs ship installable, each previewable against your last 30 days before it applies.
@sanction/sdk publish is still pending the npm scope. The package builds, typechecks, and passes its 55 tests in-repo — install from sdk/ until it lands.
Full history: v0.7.0...v0.8.0
v0.7.0 — adopt first, enforce when the numbers say so
v0.6.0 made governance drop-in and provable. v0.7.0 makes it adoptable — you don't have to flip enforcement on to start.
Highlights
- Observe mode — the do-nothing on-ramp. Set a pool to
observeand the real decision engine runs on every request and records exactly what it would have done — blocking nothing, moving no counters, paging no one (freeze and no-policy still enforce). The new Observe console reads those rows back as the flip-to-enforce case: per pool over 7 days, what enforcement would have denied or escalated, the dollars behind it, the exact codes that would fire — the real ledger with enforcement stood down, never a simulation. Flip a pool observe→enforce in one confirm-gated click; the policy revision chain records precisely when enforcement went live. Point Sanction at a live fleet, watch a week, enforce when the numbers convince you. - Sanction Local — from runtime to install. The air-gapped runtime now has its install package: the no-egress policy pack (only on-box tools pass; every cloud call denies and persists as evidence) and the Audit console's one-click signed, hash-chained evidence export an assessor verifies self-contained. Regulated practices can actually stand it up.
@sanction/sdkis publish-ready.0.6.0, FSL-licensed, with the escalate→grant loop closed in the client — poll a pending approval for its one-use grant and redeem on retry.npm install @sanction/sdkonce the publish workflow runs.- The approval email lands you on the decision. Escalation notices — email, Slack, signed webhook — now deep-link to that pending request, not a generic inbox. One click from the alert to the decision waiting on you.
- Pay-per-crawl, governed. The first mandate-authority slice: when the metered web answers
402with a price,sanctionedFetchruns the quote through/authorizeas a real spend decision — budgets, escalation, and audit before a cent of payment intent leaves your stack.
Also since v0.6.0
- Org roots read the whole subtree — a parent wallet's Overview, Spend, Tokens, Outcomes, Credentials, and Approvals show every pool beneath it instead of an empty page (a no-op for leaf operators).
- Three staged demo companies with 30-day histories and a daily warm pulse; a dedicated
/consultingservices page.
Full detail: changelog · roadmap · Observe your fleet first
v0.6.0 — drop-in governance, provable history
v0.6.0 ships what a governance layer must do to be adopted and believed: drop in without a rewrite, and prove its own record.
Highlights
- Framework adapters — the tool runs behind the decision. The SDK's new adapter layer puts authorization in front of execution:
authorizeToolwraps any tool thunk (approved → run, escalated → wait for the one-use grant, denied → a typed planning outcome, not a crash),SanctionMiddlewarewraps everything, andsanctionToolbinds natively to Vercel AI SDK tools. The model plans freely; the tool executes behind an approve. - Tamper-evident audit exports.
GET /v1/audit/exportreturns your decision history as a signed, hash-chained document — alter, drop, or reorder any row and the chain breaks at a named link.POST /v1/audit/verify(or any conforming verifier — it's self-contained) proves nothing changed after signing. Governance as cryptographic evidence. - What-if, replayed in order.
POST /v1/policy/simulatewithmode: "sequential"replays your real week chronologically — an early simulated denial frees budget for the request that came after, exactly as it would have lived. - The PDP grows armor. AuthZEN hardening sprint 2: single-use denial binding tokens (jti consumed atomically with the escalation it opens), batch pre-validation so a malformed sibling can't burn a grant, timeout-approvals that mint a redeemable grant instead of a dead loop, and per-agent rate limits with
Retry-Afteron all four endpoints. - Capabilities ask first from any MCP host.
sanction_authorize_capabilitybrings skill/plugin/API governance to the MCP runtime — same ladder, same inbox, same one-use grants.sanction-mcp0.5.0, ten tools,npx sanction-mcp. - The org owner sees the whole org. The console's Audit page now reads your entire wallet subtree — every department pool's decisions, tokens, and secret access, pool-attributed — and the Approvals inbox shows escalations waiting in the pools below you, read-only by design. The CFO who set the department budgets watches the same tree enforce them.
Also in this release
- The storefront names the internal-governance buyer: departments as wallets, cost centers, chargeback for finance — and
/consultingno longer 404s. - CI now pins the decision-note → machine-code contract (reworded reasons fail the build, not your agents) and the coverage ratchet holds at its new floors.
v0.5.0 — one engine, every surface: AuthZEN + MCP reach parity
Ten days, twenty-two changelog entries. v0.2.0 governed spend; v0.5.0 governs the fleet — and proves it.
Highlights
- One engine, every surface. Sanction's core guarantee — same request, same policy, same state, same decision — now holds across the native API, the OpenID AuthZEN 1.0 PDP, and MCP. Frozen wallets, cost-per-outcome ceilings, and all three token-budget horizons enforce identically everywhere, pinned by a cross-surface parity test suite.
- Spend answers to outcomes. Your systems attest results (
POST /v1/outcomes— an enrollment, a booking); a wallet with acost_per_outcomeceiling escalates every further charge once its windowed ratio crosses the line. Around it, the two controls a CFO reaches for: wallet freeze (one call pauses a subtree across every surface, deleting nothing) and atomic budget reallocation between sibling pools. - Decisions are evidence. Every decision persists the policy revision and exact engine context it evaluated;
GET /authorize/{id}/evidencereplays it and reports whether the outcome reproduces. Every denial answers four questions — what happened, why, what changes the answer, where's the proof — with a signed appeal path on hard budget denials. - What-if before you commit.
POST /policy/simulatereplays your real history under a candidate policy — as-recorded or sequentially, where an early denial frees budget downstream — and policy packs ship with a 30-day simulated preview before one-call install. - Seats you can hand around. Agents became seats: holders, expiries that fail closed on both auth planes, rotation that moves the person while history stays, batch creation across a fleet — with per-seat monthly token budgets and pooled per-department daily caps enforced at the gateway.
- Approvals that find you. Escalations land in Slack natively; human approvals mint single-use, TTL'd grants; the loop speaks AuthZEN's AARP profile end-to-end.
- The audit plane. One unified feed for decisions, token usage, and secret access (CSV included), day-bucketed reporting over any range, a Monday digest, and DB-level tenant isolation (Postgres RLS) underneath it all.
Also in this release
- TypeScript SDK (
@sanction/sdk) with framework adapters for the Vercel AI SDK, plus runnable LangChain and Bedrock Action Group guides. - Gateway metering extended to Perplexity; provision authorization (
allocate) joins spend and tool governance. sanction-mcp0.4.0: outcome logging, escalation polling viasanction_check_authorization, eight tools total —npx sanction-mcp.
Next up, already on main: tamper-evident audit exports — signed, hash-chained decision history any auditor can verify offline.
v0.2.0 — framework guides, public roadmap, clearer positioning
First feature release since going public.
Highlights
- Framework integration guides live on getsanction.com/docs — drop Sanction into your agent in minutes: Quickstart, Vercel AI SDK, LangChain, CrewAI.
- Build in public — a public roadmap + changelog + community idea board: submit features and vote on what we build next.
- AIIA dogfood — reference architecture + runnable example mapping AUTO/SUPERVISED/GATED execution to the approve/escalate/deny ladder.
- Account tree — govern many agents under one master account, with per-tenant budgets and subtree spend rollup.
Improvements
- Clearer positioning: Sanction is the authorization layer for AI agents, with an honest integrations story (not sanctions/AML screening).
- Gateway now meters the OpenAI Responses API, not just Chat Completions.
sanction-mcpbumped to 0.2.0.
The spend firewall is enforced and demoable today. The credential vault and clearance system are on the roadmap and not yet hardened for production — see the docs.
v0.1.3 — Sanction
First public release of Sanction — the trust and governance layer for autonomous AI agents.
What's live
- 📦 npm:
sanction-mcp@0.1.3—npx sanction-mcp - 🌐 MCP Registry:
io.github.ericlovold/sanction—active - 🔗 Site / API: https://getsanction.com
Capabilities
- Agent Wallet — spend authorization with configurable policy; per-agent daily/monthly budgets
- Credential Vault — AES-256-GCM secrets, scoped 15-min execution JWTs, full audit log
- Clearance Levels — 1–5 domain authorization
MCP setup
{
"mcpServers": {
"sanction": {
"command": "npx",
"args": ["sanction-mcp"],
"env": {
"SANCTION_API_URL": "https://getsanction.com/api/v1",
"SANCTION_API_KEY": "pxy_...",
"SANCTION_WALLET_ID": "wallet_..."
}
}
}
}Distribution: MCP server · REST API (x-api-key) · AWS Bedrock Action Group.
🤖 Generated with Claude Code