Runtime enforcement and evidence for AI governance

The AI enforcement layer.

Every model, tool and agent call is checked against your policy in line. Every decision leaves a signed record you can prove to anyone.

Source-available. Self-host in minutes. No account.

Your AI
The layer
Where it goes
Apps
Agents
CI & batch
pistra
Enforce
allow
policy on the key, the model, the tool
Redact
4111·1111→••••
rewritten in the stream, both ways
Meter
tokens counted
budget held
Record
9f2c…a41
signed, chained, in order
Models
openaianthropicgeminibedrock
MCP servers
githubjirafiles
Every call crosses the layer·nothing routes around it
7 µs
of its own work on a passthrough request
< 700 ns
for key, rules, budget reserve and settle
18 µs
to inspect a 20-turn conversation for PII, cached
1 binary
no database, no sidecar, raft inside

Measured on an Apple M4 over loopback. How, and what it means

What this is

An enforcement layer is the process between an application and a model that can refuse a call, change what it carries, and prove what it did.

What an AI enforcement layer is

Measured

314of 315

Change the language, change the verdict.

315 red-team prompts, annotated into ten languages by the paper's own annotators. One meaning per row, so the right answer is the same answer ten times. A widely deployed open guard model gives a different one on 314 of them.

It flags none of the English, 12% of the Italian, 76% of the Arabic and 98% of the Bengali. German, on a set of its own, fires on none of 27. Nothing visible from outside the model says which of your languages is which.

pistra guardrails eval scores any ONNX checkpoint you pin against your own annotated data, through the same inspection a request goes through. A profile then chooses which checkpoint inspects which traffic.

Access

Every model, tool and agent behind one door.

Teams get keys, budgets and the models they are allowed. MCP servers and peer agents sit behind the same door as the models, and clients find them through it: pistra serves the registry, and every connect URL in it is pistra's own address.

the whole migration
base_url = "https://api.openai.com/v1"
+base_url = "https://pistra.internal/v1"

The SDKs they already use change one line. Nothing else in the client moves.

  • Virtual keys with a profile. What a key may call, and how much, decided once per team.
  • Budgets that stop. Tokens or cost, reserved before the call and settled after it.
  • Every provider, one dialect. OpenAI, Anthropic, Gemini, Bedrock, vLLM and the rest, translated in place.
  • MCP, governed. Tool calls policed at the hop, and a private registry on the official v0.1 API, so a registry-aware host needs one base URL.
  • Peer agents, fronted. An A2A agent answers at pistra's address, with its card projected there and signed, so a peer can check the card it discovered is the card you served.
Govern your first provider
KeysProfilesBudgetsModels
keyprofilebudget
support-botpistra_…9f2Asupport62% of 2M tok / dayactive
ci-evalpistra_…Tt09ci-bots8% of 500k tok / dayactive
finance-apppistra_…Pq77finance97% of 1M tok / daynear cap
data-agentpistra_…7b01agents0% of 250k tok / dayrevoked

Enforce

Nothing leaves that shouldn't.

Card numbers, identifiers and secrets are found in the stream and rewritten before the provider sees them, and turned back for the tools you trust. A refusal names its rule, and says why.

Redact PII from model output
  • Redaction in the stream, on the way in and the way out, without buffering the response.
  • Format-preserving. A replaced card is still a valid card, so what is downstream keeps working.
  • Rules in CEL on the key, the model, the tool and what the detectors found.
  • Slow detectors without the latency. Run a model-backed check beside the stream, enforce from the next turn.
  • Detectors measured, not assumed. The reports say which models we rejected, and what each one costs in the languages you serve.
what the client sent

Please cancel my card 4095260993934932, my id is 1044880134, and mail me at aarav@example.com.

pii · fpe · placeholder
what the provider received

Please cancel my card 6880989289285872, my id is <SA_NATIONAL_ID_1>, and mail me at <EMAIL_ADDRESS_1>.

the card is still sixteen digits and still passes Luhn, reversible only by this gateway

403
sa-ndmo-personal-data-abroad-needs-approval guardrail rule
personal data is processed outside the Kingdom only through a provider whose metadata declares the written approval as transfer_basis

Prove

Evidence, not a claim.

Every decision is a signed, chained record that names the rule and the control it stood for. Your governance platform writes the policy it wants enforced, and reads the decisions back.

#1181a41c…f0
#11827d08…3b
#1183e92a…c7
headwitnessed
"event": "guardrail.decision",
"outcome": "redacted",
"actor": {"kind": "virtual_key", "name": "support-bot"},
"rule": "cards",
"controls": ["pci-dss:3.4", "acme:DP-02"],
"sig": "ed25519:node-0 …"
$ pistra audit verify -heads heads.json export.jsonl
node-0 · 1,183 records · complete to the witnessed head · nothing altered
Connect your AI governance platform

Deploy

Runs where you run.

Keys, budgets and certificates live in the binary's own raft log, so there is no Postgres and no Redis to run, back up or make highly available. Three replicas are the cluster.

What a cluster survives

Run it yourself. Today.

One chart or one container, and the configuration reference for everything after that.

$ helm install pistra oci://ghcr.io/pistra-dev/pistra/charts/pistra
$ docker run ghcr.io/pistra-dev/pistra -upstream https://api.openai.com