If you're shipping AI agents in the EU or selling to public-sector buyers who care about auditability, this proxy wraps your MCP servers and gates every tool call against a configurable policy (allow, block, escalate). It writes a hash-chained, tamper-evident audit trail that an outside auditor can verify without trusting your infrastructure, and it can anchor the chain head to an RFC 3161 timestamp authority for provable time. The engine blends five scoring signals and adapts as real outcomes come back. It produces article-level EU AI Act compliance reports in JSON, PDF, or HTML, marking gaps honestly instead of rubber-stamping them. Runs locally, no telemetry. The benchmarks show 84.7% recall at 4.1% false positives with 140 microsecond overhead per call.
Your AI agent transferred the funds, wrote the file, called the tool. Later, someone who does not trust you asks you to prove exactly what it did and why. A regulator, an auditor, a customer after an incident. Your own logs will not settle it, because you could have edited them.
Vaara is an open-source evidence layer for AI governance. It checks every agent tool call against your policy, writes the call and its outcome into a hash-chained, signed record, and binds that record to your machine's own TPM 2.0 hardware root. An outside party can verify the whole trail offline, with no access to your system and none of your software. EU AI Act Article 12 record-keeping is what it was built for; it answers any "show me what the agent actually did" just as well.
It runs entirely in your own environment. No SaaS, no telemetry. Python 3.10+, zero runtime dependencies.
pip install vaara
Releases ship SLSA Build Level 3 provenance, verifiable with slsa-verifier verify-artifact. Optional ML classifier: pip install 'vaara[ml]'.
from vaara.pipeline import InterceptionPipeline
pipeline = InterceptionPipeline()
result = pipeline.intercept(
agent_id="agent-007",
tool_name="fs.write_file",
parameters={"path": "/etc/service.yaml", "content": "..."},
agent_confidence=0.8,
)
if result.allowed:
pipeline.report_outcome(result.action_id, outcome_severity=0.0)
else:
print(result.reason)
Every call gets a risk score and an allow / block / escalate decision against your policy, then the call, the decision, and the real outcome are written to the audit trail. report_outcome closes the loop: the scorer reweights based on which signals actually predicted the outcome.
That is the whole loop. The rest of this page is what makes the record worth keeping.
Writing a trail is the easy half. The half that matters is letting someone who does not trust you check it, with no key, no access, and none of your code. Every Vaara record is content-addressed and fail-closed on authenticity, and ships with public conformance vectors plus a standalone checker that imports no Vaara code, so an independent party reproduces every verdict offline.
vaara verify-bundle evidence-bundle.json
ok only when a signature is actually established, not merely present in a log. The same property drives the standards work behind SEP-2828: evidence that holds up for someone who runs none of your software. The full verifier set, the trust model for each verb, and where trust comes from in each case are in docs/verifying-evidence.md.
To check that claim yourself, without installing Vaara, run the standalone checker against the published vectors. Its only dependencies are cryptography and rfc8785:
git clone https://github.com/vaaraio/vaara
cd vaara
pip install cryptography rfc8785 # the checker's only dependencies
python tests/vectors/external_evidence_v0/_check_independent.py
It re-derives every verdict from the receipt bytes and the public key alone. The output shows the property the trail is built for: a receipt dropped from inside a declared boundary is a provable gap from the held set, with no issuer access and no external witness.
[OK] complete.contiguity: {'ok': True, 'present': 3, 'expected': 3, 'missingSeqs': []}
[OK] dropped.contiguity: {'ok': False, 'present': 2, 'expected': 3, 'missingSeqs': [1]}
vaara compliance report --format json against a real trail produces an article-level evidence record an auditor reads directly. Articles with no recorded events return evidence_insufficient, not a rubber stamp.
{
"system_name": "Acme HR Assistant",
"overall_status": "evidence_insufficient",
"trail_integrity": {"size": 105, "chain_intact": true},
"articles": [
{"article": "Article 12(1)", "title": "Record-Keeping (Logging)",
"status": "evidence_sufficient", "strength": "strong", "evidence_count": 105},
{"article": "Article 15(1)", "title": "Accuracy, Robustness and Cybersecurity",
"status": "evidence_insufficient", "strength": "absent", "evidence_count": 0}
]
}
Each verdict carries the threshold-versus-observed snapshot, the rationale, and the underlying records, so a reviewer traces status back to a concrete event. The same data renders as a Notified-Body PDF, a static HTML dashboard, or a Sigstore-signed handoff envelope. See docs/COMPLIANCE.md.
vaara verify-contiguity). Off by default.Native adapters route the major Python agent frameworks through the same pipeline, each via the framework's own hook, emitting identical audit events:
| Framework | Entry point |
|---|---|
| LangChain | VaaraCallbackHandler, vaara_wrap_tool |
| CrewAI | VaaraCrewGovernance |
| OpenAI Agents SDK | VaaraToolGuardrail, vaara_wrap_function |
| MCP server | vaara.integrations.mcp_server |
To put Vaara in front of an MCP server, run it as a proxy. Every tools/call routes through the pipeline before reaching the upstream; allowed calls forward transparently, blocked calls return an MCP error.
vaara-mcp-proxy \
--upstream npx --upstream-arg -y --upstream-arg @sap/mdk-mcp-server \
--db ./mcp_audit.db
Point your MCP client (Claude Code, Cursor, any host) at the proxy instead of the upstream. There is also an HTTP API (pip install 'vaara[server]', vaara serve) and a first-party TypeScript client on npm (@vaara/client) for non-Python agents. Framework details, the cloud and OSS guardrail adapters (Bedrock, Azure, GCP, NeMo, Guardrails AI, LLM Guard, Rebuff), and the multi-tenant proxy are in docs/adapters.md.
Each risk score blends five expert signals and keeps adapting as outcomes come back, and it carries a confidence interval with a coverage guarantee that holds regardless of the input distribution. On a held-out adversarial corpus the classifier reaches 84.7% recall (95% Wilson [82.4, 86.7]) at a 4.1% false-positive rate, and 1.2% FPR on benign calls under live injection pressure. The hot-path rule scorer adds 140 µs mean per call on commodity CPU; the ML classifier is opt-in (vaara[ml]) and off that path. Every figure is reproducible via make bench.
Method and per-cell breakdown: docs/architecture.md and bench/.
Details and the offline checkers for each: docs/standards.md.
| Path | Contents |
|---|---|
| docs/verifying-evidence.md | Every verifier and its trust model |
| docs/architecture.md | Scoring, conformal coverage, time anchor, formal properties |
| SPEC.md | The canonical vaara.receipt/v1 receipt format spec |
| docs/standards.md | SEP-2828, SEP-2787, OVERT, the sovereign inference harness |
| docs/adapters.md | Framework and cloud/OSS guardrail adapters, multi-tenant proxy |
| docs/COMPLIANCE.md | EU AI Act and DORA article mapping, eval numbers |
| CHANGELOG.md | Version-by-version evolution |
| docs/PRIOR_ART.md | When each concept first shipped, plus adjacent work |
Vaara helps deployers assemble evidence for their own conformity work. It does not certify compliance or constitute legal advice. Deployers own their obligations under the EU AI Act and other applicable law.
AGPL-3.0-or-later. See LICENSE.