Skip to content
browse the docs

Local Setup Guide

vanzik v2.0updated view on github

Get Vanzik running on your machine in under 5 minutes.

Prerequisites#

Tool Version Check
Go (only to build from source or go install) 1.26+ go version
Git (only to build from source) any git --version
Python (optional, for the SDK) 3.10+ python --version
Node.js (optional, for the TS SDK) 20+ node --version
Docker (optional) any docker --version

What you're setting up#

Vanzik is the wire-level checkpoint that sits between your agent and everything it touches. It runs as one or more of three enforcement layers, plus the Vanzik server that owns policy + audit + approvals.

Layer Binary Use for Code change
MCP traffic vanzik-mcp-gateway Claude Desktop, Cursor, Cline, Continue, Zed None
LLM API calls vanzik-llm-proxy OpenAI / Anthropic SDK code One env var
Direct calls Python / TypeScript SDK + adapters Custom code, framework integrations Per-call guard.check(...)

Layer-specific quickstarts: QUICKSTART_MCP.md · QUICKSTART_LLM_PROXY.md. The rest of this guide covers building the binaries, running the server, and using the SDK.

Quick Start#

1. Install#

The installers download the prebuilt binaries for your OS and CPU, check them against the release's checksums.txt, install all three binaries, and write a starter policy if you don't have one yet. Running the same command again updates to the latest release.

Upgrading from AgentGuard 1.x (this project's name before 2.0)? The same commands move your AgentGuard setup over (its folders, database, login service and coding-agent hooks) with vanzik migrate --from-agentguard; see MIGRATION.md.

# Linux / macOS — binaries in ~/.local/bin (or /usr/local/bin as root),
# starter policy in ~/.config/vanzik/default.yaml (or /etc/vanzik/ as root)
curl -fsSL https://github.com/lictorate/vanzik/releases/latest/download/install.sh | sh
# Windows — binaries in %LOCALAPPDATA%\Programs\Vanzik\bin (added to your user PATH),
# starter policy in %APPDATA%\vanzik\default.yaml
irm https://github.com/lictorate/vanzik/releases/latest/download/install.ps1 | iex
Variable Effect
VANZIK_VERSION Install this version (e.g. 2.0.0) instead of the latest. Only 2.x versions can be installed: 1.x releases were AgentGuard, with agentguard_* archives
VANZIK_INSTALL_DIR Install the binaries here
VANZIK_DOWNLOAD_URL Download the release files from this base URL (a mirror, or an internal server for air-gapped hosts)
VANZIK_NO_MODIFY_PATH=1 Windows only: leave the user PATH unchanged

The installers never overwrite an existing starter policy. To check provenance as well as checksums, download an archive from the releases page and run gh attestation verify <archive> --repo lictorate/vanzik.

Next, run vanzik setup. From a menu, it starts Vanzik at login (no admin rights), protects it with an API key only you can read, and shows how to connect the SDKs and Claude Desktop; the same menu updates and uninstalls later (CLI.md).

If you'd rather run the server yourself, the commands below work without the leading ./, and you can leave out --policy configs/default.yaml: server, validate and check find the installer's starter policy on their own (CLI.md).

Update#

Run vanzik setup and choose Update: it downloads the new release, checks it against checksums.txt, swaps the binaries and restarts the server. Or run the same install command again. It replaces the three binaries, keeps your policy, and says what changed: Updated Vanzik <current> -> <latest>, Reinstalled Vanzik <version> (it was already on this version), or — when VANZIK_VERSION pins an older release — Downgraded Vanzik <current> -> <older> followed by a warning. The vanzik CLI prints a one-line notice with the right command when a newer release is out (server never checks; see CLI.md).

Uninstall#

Run vanzik setup and choose Uninstall…: it also removes the login service, works offline, and asks whether to keep your policy, key and data. Or use the installer:

# Linux / macOS (add --purge to delete the policy folder too)
curl -fsSL https://github.com/lictorate/vanzik/releases/latest/download/install.sh | sh -s -- --uninstall
# Windows (also set $env:VANZIK_PURGE=1 to delete the policy folder too)
$env:VANZIK_UNINSTALL=1; irm https://github.com/lictorate/vanzik/releases/latest/download/install.ps1 | iex

The uninstall removes the three binaries — on Windows also the folder's entry on your user PATH — and keeps your policy folder, printing where it is. Audit logs and the state database live wherever you ran vanzik server, so it cannot know their path and leaves them alone. Run it as the same user that installed (with sudo for a root install in /usr/local/bin); with VANZIK_INSTALL_DIR set, it removes from that folder. On Windows, stop any running Vanzik first: the uninstall refuses rather than removing half of it. VANZIK_UNINSTALL=1 works on Linux and macOS too; on Windows the variable is cleared once read, so a later install in the same window installs.

For the container image, stop and remove the container; docker volume rm vanzik-audit (or whatever volume you mounted at /var/lib/vanzik) deletes the audit trail.

Or build from source#

git clone https://github.com/lictorate/vanzik.git
cd vanzik

# Central server (always needed)
go build -o vanzik ./cmd/vanzik

# MCP Gateway (only if you're integrating MCP clients)
go build -o vanzik-mcp-gateway ./cmd/vanzik-mcp-gateway

# LLM API Proxy (only if you're proxying OpenAI / Anthropic SDK traffic)
go build -o vanzik-llm-proxy ./cmd/vanzik-llm-proxy

On Windows append .exe to each -o target. Or install everything from a remote tag:

go install lictorate.com/vanzik/v2/cmd/vanzik@latest
go install lictorate.com/vanzik/v2/cmd/vanzik-mcp-gateway@latest
go install lictorate.com/vanzik/v2/cmd/vanzik-llm-proxy@latest

2. Validate the Default Policy#

./vanzik validate --policy configs/default.yaml
# Output: VALID: default-sandbox — 61 rules across 5 scopes  (numbers vary as the default ships more rules)

3. Start the Server#

# Basic
./vanzik server --policy configs/default.yaml

# With the dashboard, logging each policy reload (reloading is always on)
./vanzik server --policy configs/default.yaml --dashboard --watch

# Custom port
./vanzik server --policy configs/default.yaml --port 9090 --dashboard

4. Verify It's Running#

curl http://localhost:8080/health
# {"status":"ok","version":"2.0.0"}

Open http://localhost:8080/dashboard in your browser to see the live dashboard.

5. Test a Policy Check#

# This should be ALLOWED (ls is in the allow list)
curl -X POST http://localhost:8080/v1/check \
  -H "Content-Type: application/json" \
  -d '{"scope": "shell", "command": "ls -la", "agent_id": "test"}'

# This should be DENIED (fork bomb)
curl -X POST http://localhost:8080/v1/check \
  -H "Content-Type: application/json" \
  -d '{"scope": "shell", "command": ":(){ :|:& };:", "agent_id": "test"}'

# This should REQUIRE_APPROVAL (sudo)
curl -X POST http://localhost:8080/v1/check \
  -H "Content-Type: application/json" \
  -d '{"scope": "shell", "command": "sudo apt install vim", "agent_id": "test"}'

# Filesystem scope — DENIED by the system-directories write deny ("Writing to system directories is blocked")
curl -X POST http://localhost:8080/v1/check \
  -H "Content-Type: application/json" \
  -d '{"scope": "filesystem", "action": "write", "path": "/etc/passwd", "agent_id": "test"}'

# Network scope — ALLOWED (api.openai.com is whitelisted)
curl -X POST http://localhost:8080/v1/check \
  -H "Content-Type: application/json" \
  -d '{"scope": "network", "domain": "api.openai.com", "agent_id": "test"}'

Authentication#

By default (--api-key not set) the server binds to 127.0.0.1 only — safe for local dev, but approve/deny/audit/status are unauthenticated. For anything beyond local dev, set an API key:

./vanzik server \
  --policy configs/default.yaml \
  --api-key YOUR_SECRET \
  --dashboard

# Or via environment (server + CLI both read this):
export VANZIK_API_KEY=YOUR_SECRET
./vanzik server --policy configs/default.yaml --dashboard

Which endpoints the key gates (and which stay open), the dashboard login/CSRF flow, Bearer-vs-session curl recipes, and CORS (--allowed-origin) are documented once in DEPLOYMENT.md with the endpoint table in API.md.


Using the Python SDK#

Install#

# From PyPI
pip install vanzik

# With framework adapters
pip install vanzik[langchain]
pip install vanzik[crewai]
pip install vanzik[browser-use]
pip install vanzik[all]

# Or from source (editable / development)
cd plugins/python
pip install -e ".[dev]"

Basic Usage#

from vanzik import Guard

# base_url / api_key fall back to VANZIK_URL / VANZIK_API_KEY.
guard = Guard("http://localhost:8080", agent_id="my-agent", api_key="YOUR_SECRET")

result = guard.check("shell", command="ls -la")
if result.allowed:
    run_it()

That's the whole core loop. The rest of the SDK surface — the approval flow (wait_for_approval), programmatic approve/deny, cost guardrails, the @guarded decorator, failure modes, and testing recipes — is documented once in SDK_PYTHON.md. The framework adapters (LangChain, CrewAI, browser-use, MCP) with their scope-inference rules and per-framework gotchas live in ADAPTERS.md.


Using the TypeScript SDK#

Install#

# From npm
npm install @lictorate/vanzik

# Or from source: build the package, then install it into your project
cd plugins/typescript
npm ci
npm run build
cd /path/to/your-project && npm install /path/to/vanzik/plugins/typescript

Usage#

import { Vanzik } from '@lictorate/vanzik';

const guard = new Vanzik({
  baseUrl: 'http://localhost:8080',
  agentId: 'my-bot',
  apiKey: process.env.VANZIK_API_KEY,
  // failMode: 'deny' (default) — server unreachable ⇒ check() returns DENY.
});

const result = await guard.check('shell', { command: 'ls -la' });
if (result.allowed) { /* proceed */ }

The TypeScript surface mirrors the Python one — waitForApproval, approve/deny, cost checks, and the guarded higher-order wrapper. See the package README in plugins/typescript/ for the full API.


Using the CLI#

# Start the server
vanzik server --policy configs/default.yaml --dashboard --watch

# With authentication (also reads VANZIK_API_KEY from the environment)
vanzik server --policy configs/default.yaml --api-key YOUR_SECRET --dashboard

# Validate policy files (no server needed)
vanzik validate --policy configs/default.yaml

# Approve / deny — accept --api-key or VANZIK_API_KEY env var.
vanzik approve --api-key YOUR_SECRET ap_abc123def456
VANZIK_API_KEY=YOUR_SECRET vanzik deny ap_abc123def456

# Check server status and pending approvals (auth required if server is gated)
vanzik status --api-key YOUR_SECRET

# Query the audit log with filters
vanzik audit --agent my-bot --decision DENY --limit 20 --api-key YOUR_SECRET

# Print version
vanzik version

The full server flag table (persistence, audit rotation, buffered async logger, session-cost TTL, base-url/CORS) lives in CLI.md; vanzik server -h prints the same list.

Wire-level enforcement points#

Two additional binaries enforce at the wire. Both reach vanzik server at --guard-url, which defaults to $VANZIK_URL, else http://127.0.0.1:8080, and both read VANZIK_API_KEY for authenticated server calls.


Using Docker#

docker build -t vanzik:latest .

# The API key is required: without it the server binds 127.0.0.1 inside
# the container and the published port is unreachable.
# Default policy is baked in; mount a named volume so the audit log
# survives container restarts.
export VANZIK_API_KEY="$(openssl rand -hex 32)"
docker run -d -p 8080:8080 --name vanzik \
  -e VANZIK_API_KEY="$VANZIK_API_KEY" \
  -v vanzik-audit:/var/lib/vanzik \
  vanzik:latest

make docker-run does the same build and run, and stops early if VANZIK_API_KEY isn't set.

Custom-policy mounts, the non-root uid-10001 volume-permission gotcha, Compose, and Kubernetes manifests are in DEPLOYMENT.md.


Configuration#

Policy Files#

Policies are YAML files in configs/. See the included examples:

File Use Case
configs/default.yaml Safe sandbox defaults
configs/examples/research-agent.yaml Permissive research agent
configs/examples/trading-bot.yaml Strict financial trading agent

Policy Hot-Reload#

Policy edits take effect without a restart: the server always watches the --policy file (fsnotify, falling back to a 2 s modification-time poll where fsnotify isn't available). --watch only adds a log line for each reload:

vanzik server --policy configs/default.yaml --watch
# 2026/09/23 21:59:11 Policy reloaded: default-sandbox (61 rules)

Everything else in the policy file#

Per-agent overrides (agents:), notifications (Slack / webhook / console), per-scope rate limits, cost guardrails, conditional rules, and the tool_scope_map are all part of the policy YAML — the schema with examples for each lives in POLICY_REFERENCE.md; server-side tunables (session TTL, body caps, audit query limits) in CONFIG.md.


Running Tests#

The fastest path is make test-all, which runs all four suites (Go, policy YAML validation, Python SDK, TypeScript SDK) in sequence and prints a PASS / FAIL / SKIP summary. An invalid policy or a failing configs/tests case fails the policy suite, and the Python suite installs the same extras as CI (.[dev,langchain,crewai,mcp,openai-agents]). Missing toolchains (no python, no npm) report SKIP cleanly so Go-only contributors aren't penalised. The script exits 0 if no suite failed and 1 if any did. See CONTRIBUTING.md.

make test-all                   # everything
# or, narrow:
./scripts/test-all.sh --skip-ts
./scripts/test-all.sh --no-race      # drop the Go race detector for speed

Per-suite manual invocations:

# Go tests with race detection + coverage
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# Policy YAML validation (configs/default.yaml and every configs/examples/*.yaml; builds ./vanzik)
make validate

# Python SDK tests (adapter unit tests need framework extras)
cd plugins/python
pip install -e ".[dev,langchain,crewai,mcp,openai-agents]"
pytest -v --cov=vanzik

# TypeScript SDK tests
cd plugins/typescript && npm install && npm run build && npm test

Project Structure#

The main directories and files; the lists below are not exhaustive (pkg/ also holds depaudit, deprecation, internal, metrics, persist, report and store, and the Python adapters include openai_agents.py and the shared _common.py).

vanzik/
├── cmd/
│   ├── vanzik/                  # Central server CLI (serve / validate / check / migrate / …)
│   │   ├── main.go
│   │   ├── check_cmd.go
│   │   └── update_check.go
│   ├── vanzik-mcp-gateway/      # MCP Gateway binary
│   │   └── main.go
│   └── vanzik-llm-proxy/        # LLM API Proxy binary
│       └── main.go
├── pkg/
│   ├── policy/                      # Policy engine (YAML parsing, rule evaluation, providers)
│   ├── proxy/                       # Central HTTP server + dashboard + approval queue
│   ├── audit/                       # Audit logging (JSON lines + rotation + buffered async)
│   ├── notify/                      # Webhook / Slack / console notifications
│   ├── ratelimit/                   # Token-bucket rate limiter
│   ├── mcpgw/                       # MCP Gateway core (upstream multiplexing, namespacing)
│   ├── llmproxy/                    # LLM API Proxy core (OpenAI / Anthropic stream gating)
│   └── migrate/                     # On-disk schema migrations (audit / checkpoint format)
├── plugins/
│   ├── python/                      # Python SDK + framework adapters
│   │   ├── vanzik/
│   │   │   ├── __init__.py          # Guard, @guarded, exception hierarchy
│   │   │   └── adapters/
│   │   │       ├── langchain.py     # GuardedTool, GuardedToolkit (subclasses BaseTool)
│   │   │       ├── crewai.py        # GuardedCrewTool (subclasses crewai BaseTool)
│   │   │       ├── browseruse.py    # GuardedBrowser / Page / Frame
│   │   │       └── mcp.py           # GuardedMCPServer + Python MCP gateway
│   │   ├── pyproject.toml
│   │   └── README.md
│   └── typescript/                  # TypeScript SDK
│       ├── src/index.ts
│       └── package.json
├── configs/                         # Policy files
│   ├── default.yaml
│   └── examples/
├── examples/                        # MCP-client + SDK config snippets ready to copy
├── docs/                            # Documentation
├── Dockerfile                       # Image shipping the `vanzik` server binary
├── Makefile                         # build / test / test-all / docker / …
└── README.md