Skip to main content

Varden

Varden logo

License Release Build Platforms Agent Governance

Using Varden? Drop a note — I read everything: open a blank issue titled "Using this"

Project links: Source · Issues · Security

Your developers are using Cursor. It's calling APIs, running git commands, talking to external services, executing shell commands.

Do you know what it's doing?

Now multiply that by a team of ten, all running AI agents with MCP access to your infrastructure. Nobody has a complete inventory of what those agents can touch. Nobody sees it when one does something unexpected. Nobody knows when a new capability quietly appears.

A runtime governance layer for AI agents, tools and MCP servers.

Varden observes, governs, and audits agent activity in real time.

Varden is the thing watching.


Tell your agent to secure itself

Give a compatible coding agent the Varden security skill and say:

Secure this agent with Varden.

Agent:
  installs/configures Varden
        ↓
  routes supported surfaces
        ↓
  asks Varden for posture
        ↓
  reports Varden's authoritative result

Don't ask your agent whether it's secure. Ask Varden to prove what is enforced.

The skill is not the firewall. Varden is.

varden posture
varden posture --json

Example of an honest result (gaps are expected to be visible):

Protection
  Network      PARTIAL
  Subprocess   ENFORCED
  Filesystem   PARTIAL
  MCP          NOT_ROUTED

Result
  NOT FULLY ROUTED
# After pip install varden — print the shipped skill path
varden skill path

# Copy into an agent skills directory (refuses to overwrite)
varden skill install --target ~/.cursor/skills
# or, from a clone:
# cp -R skills/varden-security <your-agent-skills-dir>/

Not every agent runtime supports skills; where unsupported, paste the skill instructions or drive the same workflow manually with the CLI below.


Try it now

pip install varden
varden demo

That's it. Varden starts, bootstraps a baseline policy, runs demo agents, and opens the dashboard showing blocked, warned, and monitored actions.

Or clone and run from source:

git clone https://github.com/markndg/varden
cd varden
python -m venv .venv && source .venv/bin/activate
pip install -e .
varden demo

Wrap your CLI tools with Varden session:

export VARDEN_BASE_URL=http://127.0.0.1:8000
export VARDEN_API_KEY=admin-demo-key
varden session . -- cursor .

Subprocess calls, HTTP requests, and LLM calls that Cursor makes now appear in your dashboard — blocked, warned, or logged according to your policy.

Note: Varden intercepts via a PATH shim. Child processes Cursor spawns will be covered; processes Cursor launches outside the shell PATH may not be. Use an interactive varden session shell for broadest coverage.

Varden dashboard — trace and flow mission control


One line protects your Python agents

import varden
import requests

varden.protect()

# Everything below is now intercepted, checked against policy, and logged.
# Nothing changes in your code. Everything changes in your visibility.
requests.post("https://partner.example/api", json={"token": "abc123"})

varden.protect() establishes an enforced runtime boundary around supported surfaces (HTTP, subprocess, filesystem where supported, tools) with mode=guarded and fail-closed control-plane semantics by default.

varden.protect(mode="strict", require_coverage=["http", "subprocess", "mcp"])

Coverage attestation (varden coverage, varden coverage --json) and authoritative posture (varden posture, varden posture --json) report ENFORCED vs UNCOVERED honestly — including limitations such as saved pre-patch function references and raw sockets. See docs/runtime-boundary.md and docs/runtime-posture.md.

Varden patches the Python runtime — requests, httpx, subprocess, filesystem APIs, OpenAI, Anthropic — so supported actions are checked before they run. Route MCP configs through varden mcp wrap for gateway enforcement. Your developers add one line. You get traces, coverage, and scoped approvals.


Enforced runtime boundary

Privileged side effects on supported surfaces must pass a shared pre-execution guard (POST /sdk/guard + PolicyEngine) before they run. The product goal is honest coverage: never claim a surface is ENFORCED if a known path can bypass it.

Surface Typical status Notes
requests / httpx / urllib ENFORCED Monkeypatch after protect()
Subprocess ENFORCED / PARTIAL Saved pre-patch refs bypass
Filesystem PARTIAL Canonical/symlink-aware targets; WRITE_CI / WRITE_CONFIG / WRITE_CODE; residual TOCTOU
MCP ENFORCED via gateway, else NOT_ROUTED Use varden mcp wrap
Raw sockets / aiohttp / urllib3-direct UNCOVERED Reported in coverage

Modes: observe · guarded (default) · strict
Fail mode: closed by default for guarded/strict (control-plane outage blocks).

Filesystem containment uses effective targets (traversal/symlink-aware) with a pre-use re-check. Coverage remains PARTIAL. See docs/runtime-filesystem-containment.md.

Persistent decisions are stored in an atomic SHA-256 hash chain; verify with varden audit verify (docs/audit-integrity.md).

Same API. Stronger boundary. Verifiable evidence.

Capability Status
Filesystem target containment supported
Filesystem full mediation PARTIAL
Audit hash chain supported
Audit verification (varden audit verify) supported
External signed checkpoint not provided
varden coverage
varden coverage --json
varden runtime readiness
varden runtime readiness --json
varden runtime self-test
varden mcp wrap ~/.cursor/mcp.json --output /tmp/mcp.wrapped.json
varden approvals pending
varden skill path

Strict mode refuses readiness when discovered relevant surfaces (for example MCP config present but NOT_ROUTED) remain unenforced, unless you explicitly accept them:

varden.protect(mode="strict", allow_uncovered=["mcp"])

Scoped approvals are HMAC-signed, single-use, and bound to action / resource / authority / trace. Import runtime-boundary-enforcement for supply-chain defaults (untrusted → CI/config/code).

Local security verification (loopback only, no external network):

python demos/runtime/run_security_verification.py
python demos/runtime/mcp_cross_server_host.py

Docs: runtime-boundary · coverage · modes · MCP gateway · approvals · limitations


What Varden covers

Action type What gets checked
Tool calls MCP / Python tools, before execution (when routed or wrapped)
HTTP/API requests Outbound calls via requests/httpx/urllib (+ payload classification)
Subprocess execution Shell commands, before they run
Filesystem (Python APIs) Sensitive paths + workspace mutation classes (WRITE_CI / WRITE_CONFIG / WRITE_CODE)
LLM calls Provider transport (OpenAI, Anthropic); tool dispatch / callbacks separately attested
MCP servers Downstream calls when routed through the Varden gateway
CLI tools kubectl, terraform, aws, gcloud, git, docker, cursor — via varden session

Decisions are allow, warn, block, require_approval, or monitor. Every decision lands in the dashboard with classifiers, risk scores, provenance/authority context, and a full trace.


Browser agents now have a tool supply chain

Websites can now dynamically expose tools to browser agents via WebMCP (document.modelContext.registerTool). That means tool metadata and tool output are untrusted input — a page can register a tool whose description tells an agent to ignore its instructions, call an unrelated wallet tool, or exfiltrate data to another origin, and the agent may never know the difference.

Varden Web Shield detects, governs and audits that surface with the same runtime-governance model Varden already uses for tool calls, HTTP requests and LLM calls: a layered classifier scans every registration and output for prompt injection, Unicode obfuscation, capability mismatch and cross-origin data flow; an explainable 0–100 risk score feeds the same policy engine (allow / warn / sanitise / require_approval / block); and every decision — plus whether it was actually enforceable in the browser — shows up in the dashboard.

pip install varden
varden web-shield demo

The demo starts Varden, seeds a Web Shield dashboard, and opens a self-contained attack lab with 20 safe, simulated cases (prompt injection, Unicode tricks, capability mismatch, lifecycle rug-pulls and cross-origin flows). Import the webmcp-web-shield policy pack to enable enforcement.

flowchart LR
    Page[Website: document.modelContext.registerTool] -->|extension or SDK| API[/webshield/* API/]
    API --> Engine[7-layer classifier + explainable risk score]
    Engine --> Policy[Varden PolicyEngine: allow / warn / sanitise / require_approval / block]
    Policy --> Dashboard[Web Shield dashboard: inventory, findings, cross-origin flows, approvals]

Also included: a Chromium MV3 browser extension with an offline-safe local fallback scanner, a framework-neutral @varden/web-shield JS SDK for first-party integrations, and a varden web-shield evaluate command that reports real precision/recall/latency against a versioned test corpus (not just claimed effectiveness). Full docs start at docs/web-shield-architecture.md; an honest list of what it doesn't do is in docs/web-shield-limitations.md.


Provenance-aware authority flow

Varden doesn't only ask whether an agent is allowed to use a tool. It asks whether the information that caused the tool call was authorised to exercise that tool's power.

This protects against Ghostjacking-style chains where untrusted content (web page, issue, MCP result, WebMCP metadata) influences an agent into exercising privileges it already possesses — reading secrets, running a shell, calling a privileged MCP server, or exfiltrating data.

Cross-server MCP causality is preserved on the supported host path: session provenance keyed by trace_id (SDK context + control plane), not by manually stuffing provenance into later tool calls. See VardenMcpHost and docs/provenance-mcp.md.

varden provenance evaluate
varden provenance demo
varden authority violations
varden authority delegations

Import the provenance-authority-defense policy pack for fail-closed defaults. Dashboard: /ui/authority (overview, attack paths, Protection Coverage).

Docs: docs/provenance-authority.md · docs/provenance-limitations.md


Rule impact intelligence

Know which rules are working, which are over-firing, and where your coverage gaps are.

Varden rule impact — heatmap of live policy impact with drilldown

Every rule shows its detection count, coverage percentage, false positive proxy, and which agents and tools it's touching. The drilldown panel shows the most recent decision for any rule in one click.


Why self-hosted matters

Most AI security products inspect prompts in the cloud. Your data leaves your infrastructure to be evaluated by someone else's service.

Varden runs on your infrastructure. Your policy file, your data, your control plane. No traffic leaves unless you decide it does.

Varden rules config — view and configure rules


Quickstart

1. Install

git clone https://github.com/markndg/varden
cd varden
python -m venv .venv && source .venv/bin/activate
pip install -e .

2. Create a policy

python -c "import json, pathlib; p=pathlib.Path('policy-packs/baseline-operational-safety.json'); pathlib.Path('policy.json').write_text(json.dumps(json.loads(p.read_text(encoding='utf-8'))['template'], indent=2) + '\n', encoding='utf-8')"

3. Start Varden

python -m varden.api --config examples/dev.env

4. Open the dashboard

  • Dashboard: http://127.0.0.1:8000/
  • Rules editor: http://127.0.0.1:8000/ui/rules
  • API docs: http://127.0.0.1:8000/docs
  • Bootstrap key: admin-demo-key

5. Run the demo

python -m varden.cli demo

Shows a blocked action, a warned action, and a clean allowed action — all visible in the dashboard immediately.


Policy model

Policies are a JSON file with four outcome lists (block, warn, monitor, allow) plus optional budget_rules for LLM spend caps.

{
  "block": [
    {"type": "tool_call", "tool": "delete_database"},
    {"type": "tool_call", "tool": "subprocess.run", "field:args.args": {"contains": "delete_database"}}
  ],
  "warn": [
    {"classifier:secrets": true},
    {"classifier:internal": true}
  ],
  "monitor": [],
  "allow": [],
  "budget_rules": [
    {
      "id": "session-default-cap",
      "type": "token_budget",
      "limit_usd": 10.0,
      "window": "session",
      "hard_cap": true
    }
  ]
}

Rules are evaluated in order: block → warn → monitor → allow. First match wins. Token budget rules run on llm_call actions before execution (pre-check) and after completion via SDK usage logging (post-record). Edit visually at /ui/rules or directly in the JSON file. Policy versions are tracked.


Token budgets (LLM cost governance)

Cap LLM spend per trace (session), workflow (daily / monthly), or both. Budget rules live in the top-level budget_rules array.

  • Pre-check (POST /sdk/guard): projects cost from model + token limits and blocks or warns before the call runs.
  • Post-record (POST /sdk/log): increments spend from provider usage metadata forwarded by the SDK.
  • CLI: varden budget status lists active budget rows from SQLite.

Import the llm-cost-governance policy pack for ready-made budget rules, or add your own budget_rules entries.

Dashboard: Rules workspace → budget tab (full editor). Overview → Token budgets panel (live spend). Rule impact → budget bucket.

Demo (with Varden running on :8000):

python demos/token_budget_agent.py

Policy pack import

Repository policy packs live in policy-packs/. Import them from the dashboard (Rules → Templates → Import & save) or via API:

curl -X POST http://127.0.0.1:8000/policy/import-pack \
  -H "x-api-key: admin-demo-key" \
  -H "content-type: application/json" \
  -d '{"pack_id":"baseline-operational-safety","mode":"merge"}'
  • GET /policy/packs — list available packs
  • GET /policy/packs/{pack_id} — fetch a pack document
  • POST /policy/import-pack — merge or replace into the active policy file

MCP tool inventory

Discover MCP servers registered in Cursor config files and compare tools against your policy coverage gaps.

  • Dashboard: Overview page → enter an MCP config path (e.g. ~/.cursor/mcp.json) → Scan path, or leave blank and use Scan defaults
  • GET /mcp/inventory — current indexed servers, tools, and uncovered tools
  • POST /mcp/scan — scan MCP configs; body may include path (string) or paths (array). Omit both to scan defaults (~/.cursor/mcp.json, project .cursor/mcp.json, and VARDEN_MCP_CONFIG_PATHS)

LangChain integration

import varden
from varden_langchain import protect_tools

varden.protect_from_env(auto_instrument=False)
tools = protect_tools(tools, agent_name='support-agent')

Pre-execution allow / warn / block on every tool call, with full trace visibility in the dashboard. Drop-in — no changes to your agent architecture.

Demos:

python demos/langchain/allow_warn_block_demo.py
python demos/langchain/sql_guard_demo.py
python demos/langchain/exfiltration_demo.py

varden session: wrap any CLI tool

The session command starts a shell with a PATH prefix so selected binaries route through Varden before running. Use it to watch — and enforce policy on — any tool your team or their agents call.

# Watch what Cursor does in the current directory
varden session . -- cursor .

# One-shot: guard a single kubectl command
varden session -- kubectl delete pod my-pod

# Passive mode: log without blocking
varden session --passive

# Strict session boundary (PATH/shim layer; still not an OS sandbox)
varden session --strict -- cursor .

Shimmed by default: cursor, kubectl, terraform, aws, gcloud, az, docker, docker-compose, git, npm, pip, pip3, railway, supabase, vercel, fly, render, psql, mysql.


Self-hosting

docker compose -f deploy/docker-compose.yml up

See deploy/self_hosting.md and deploy/operations.md for production configuration. Local defaults use SQLite. Production self-hosting should use a strong signing secret and disable the dev bootstrap auth.


Licence

Licensed under the Apache License 2.0. See LICENSE.

Metadata

Release files for varden 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for varden 0.4.1
File Size Uploaded
varden-0.4.1.tar.gz 3.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for varden 0.4.1
File Interpreter ABI Platform
varden-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 6.1 MB

Release files / varden-0.4.1.tar.gz

Download URL varden-0.4.1.tar.gz
Size 3.1 MB
Tags Source
SHA-256 checksum
How to use checksums
45251c48db20aec59226d73ea2997bdb5ffa89c76ace65969364a6513e7166c7
BLAKE2b-256 checksum
How to use checksums
ccc4c28252bc243fe2179fe1c46f53ab77d1ad72d3f7937e2e3fb90e3451e75b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release files / varden-0.4.1-py3-none-any.whl

Download URL varden-0.4.1-py3-none-any.whl
Size 3.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
b96965c2ccbb7b8041a8af7afade3c955e637d26c32d953824f08e5a416e7ef1
BLAKE2b-256 checksum
How to use checksums
61c5232dfc8d79256851cb16d871d093d6e33f84829b0fc2f0e54c3a0a32a44a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.13

Release history Release notifications | RSS feed

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page