Skip to main content

Runtime evidence layer for AI agents under the EU AI Act: policy-gated tool calls, hash-chained tamper-evident audit trails with external time anchoring, and independently verifiable attestation plus execution receipts per MCP tool call

Project description

Vaara

PyPI License CI OpenSSF Scorecard OpenSSF Best Practices Hugging Face Space

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.

Install and first call

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.

Verify it without trusting the producer

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.

What the evidence looks like

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.

What you get

  • Gate every tool call against your own policy: allow, block, or escalate.
  • A tamper-evident trail an outside party verifies without trusting your stack, with the chain head anchorable to an external RFC 3161 / eIDAS timestamp so its existence is provable against a clock you do not control.
  • Article-level EU AI Act evidence, honest about the gaps instead of papering over them.
  • Governance of the model call itself, not only the tools around it: a hardware-rooted inference receipt that a second, different local model cross-checks. This is the sovereign inference harness, new in v1.0.

Where it plugs in

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.

How it scores

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.

Full numbers, corpus, calibration, and chain of custody
  • 12,155-entry adversarial corpus (250 hand-curated + 11,905 LLM-generated), 70/15/15 split stratified by (category, source).
  • Classifier v9 (236 hand-features + 384-dim MiniLM embeddings) at calibrated threshold 0.9150 on held-out TEST n=1,827: recall 84.7% [82.4, 86.7] at FPR 4.1% [2.9, 5.7].
  • Cross-model held-out recall 66.8% [64.9, 68.7] over n=2,277 with no eval-set attacker model in TRAIN; the weakest sub-cell is data_exfil against a closed-weight model at 38.9%. This is the honest worst case; the in-distribution number above is the easier denominator.
  • BIPIA-pressure FPR on benign tool calls 1.2% [0.4, 3.6] across four agent backends (Claude Haiku 4.5, Llama-3.1-8B, Mistral-7B, Qwen-2.5-7B). Down from 35.2% on v8.
  • Multi-attacker PAIR robustness: 0/25 successes per attacker across Qwen2.5-32B, Qwen2.5-72B, Llama-3.3-70B on identical seeds, Wilson upper 13.3%.
  • Distribution-free conformal coverage on the score; MWU regret bound O(sqrt(T log N)).
  • Chain of custody: corpus, split, training commit, and bundle SHAs locked and printed by every script.

Method and per-cell breakdown: docs/architecture.md and bench/.

Standards and attestation

  • SEP-2828 signed execution records and SEP-2787 request-attestation test vectors, in the MCP standards process. A second independent implementation has reproduced the SEP-2828 conformance vectors from a clean checkout with no shared code.
  • OVERT 1.0 (overt.is): Vaara is the Arbiter and emits Protocol Profile 1.0 Base Envelopes (canonical CBOR, Ed25519) alongside every record when attestation is on.
  • Post-quantum: an optional parallel ML-DSA-65 / FIPS 204 signature over the same preimage, so a stripped post-quantum signature is a detectable downgrade rather than a silent loss.
  • Sovereign inference harness (v1.0): a local model behind a signing proxy that emits a hardware-rooted inference receipt a second local model cross-checks. Developed privately, published here under AGPL-3.0.

Details and the offline checkers for each: docs/standards.md.

Docs

Path Contents
docs/verifying-evidence.md Every verifier and its trust model
docs/architecture.md Scoring, conformal coverage, time anchor, formal properties
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

Acknowledgements

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.

License

AGPL-3.0-or-later. See LICENSE.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vaara-1.1.1.tar.gz (1.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vaara-1.1.1-py3-none-any.whl (1.0 MB view details)

Uploaded Python 3

File details

Details for the file vaara-1.1.1.tar.gz.

File metadata

  • Download URL: vaara-1.1.1.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for vaara-1.1.1.tar.gz
Algorithm Hash digest
SHA256 637fa189d7f8173c179015da2085922c861d4dd7a1164dfc0a638af263cb4d7b
MD5 2bc62b71948d1ac3f16981ce4e8c16ec
BLAKE2b-256 2d09db9eddb7e8799207a7da8ce61b17ca4ee530008e2b8442b3a4e3cf74296b

See more details on using hashes here.

Provenance

The following attestation bundles were made for vaara-1.1.1.tar.gz:

Publisher: release.yml on vaaraio/vaara

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vaara-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: vaara-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for vaara-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7fbb9c763803f4ccfcfe91e3aadc65125f2ab7ab5e16df0e100b9aca62860583
MD5 4310293633aa1a6e1f5c8cd908e5408d
BLAKE2b-256 74056480d96eb6cabcbf83d113eee3d2cfdab91e74e460340039b7aa44bef732

See more details on using hashes here.

Provenance

The following attestation bundles were made for vaara-1.1.1-py3-none-any.whl:

Publisher: release.yml on vaaraio/vaara

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page