Skip to main content

Vanzik Python SDK

Lightweight Python client for Vanzik — the firewall for AI agents.

  • Zero runtime dependencies for the core SDK (stdlib urllib).
  • Fail-closed by default — if the proxy is unreachable, check() returns DENY.
  • Framework adapters for LangChain, CrewAI, browser-use, MCP, and the OpenAI Agents SDK, gated behind optional extras.

Deep reference: docs/SDK_PYTHON.md — full API, exception hierarchy, fail-mode details, adapter internals.

Install

pip install vanzik

# With framework adapters
pip install vanzik[langchain]
pip install vanzik[crewai]
pip install vanzik[browser-use]
pip install vanzik[mcp]
pip install 'vanzik[openai-agents]'
pip install vanzik[all]

The package and the import are both vanzik.

Quick start

from vanzik import Guard

guard = Guard(
    base_url="http://localhost:8080/",   # or set VANZIK_URL
    agent_id="my-agent",
    api_key="…",                        # or set VANZIK_API_KEY (needed for approve/deny/status)
)

command = "rm -rf ./old_data"
result = guard.check("shell", command=command)

if result.allowed:
    execute(command)
elif result.needs_approval:
    print(f"Approve at: {result.approval_url}")
    # Block until a human resolves it, or 5 min deadline, whichever first
    final = guard.wait_for_approval(result.approval_id, timeout=300)
    if final.allowed:
        # Replay the approval: consumes the one-shot ALLOW, reserves cost,
        # and audits the execution. The status poll alone spends nothing.
        replay = guard.check("shell", command=command, approval_id=result.approval_id)
        if replay.allowed:
            execute(command)
else:
    print(f"Blocked: {result.reason}")

Environment variables

Var Default Used by
VANZIK_URL http://localhost:8080 Guard(base_url="") fallback
VANZIK_API_KEY (empty) Guard(api_key="") fallback; sent as Authorization: Bearer <key> on /v1/approve, /v1/deny, /v1/status
VANZIK_TENANT_ID (empty) Guard(tenant_id=None) fallback; a value other than local routes calls to /v1/t/<tenant>/…

Fail mode

# Default: fail closed. Proxy unreachable → CheckResult(decision="DENY", reason="Vanzik unreachable (deny): …")
guard = Guard("http://localhost:8080/")

# Opt in to fail open. Proxy unreachable → CheckResult(decision="ALLOW", reason="Vanzik unreachable (allow): …")
# Use only when your threat model treats Vanzik as advisory.
guard = Guard("http://localhost:8080/", fail_mode="allow")

Fail mode applies to transport failures — urllib.error.URLError (connection refused / DNS / SSL, and HTTP error statuses), OSError (post-connect timeouts and resets), json.JSONDecodeError (garbage response body) — and to responses that aren't a valid decision (a non-JSON Content-Type, or a body without decision).

The @guarded decorator

from vanzik import Guard, guarded, VanzikDenied, VanzikApprovalRequired

guard = Guard("http://localhost:8080/", agent_id="my-agent")

@guarded("shell", guard=guard)
def run_command(cmd: str):
    os.system(cmd)

try:
    run_command("ls")
    run_command("dd if=/dev/zero of=/dev/sda")  # raises VanzikDenied
except VanzikDenied as e:
    log(f"blocked: {e.result.reason}")

On REQUIRE_APPROVAL the decorator raises VanzikApprovalRequired immediately. To block until a human resolves it, opt in:

@guarded("cost", guard=guard, wait_for_approval=True, approval_timeout=300)
def expensive_call(prompt: str): ...

All Vanzik exceptions (VanzikDenied, VanzikApprovalRequired, VanzikApprovalTimeout, VanzikAuthError) extend PermissionError, so existing except PermissionError: handlers keep working unchanged.

Framework adapters

LangChain

from vanzik.adapters.langchain import GuardedToolkit

toolkit = GuardedToolkit(
    tools=my_tools,
    guard_url="http://localhost:8080/",
    agent_id="langchain-agent",
)
agent = create_react_agent(llm, toolkit.tools, prompt)

Scope is inferred from each tool's name/description (http/api→network, file/path→filesystem, browser→browser, shell→shell) and upgraded at call time if the input dict contains url, domain, or path keys.

CrewAI

from vanzik.adapters.crewai import guard_crew_tools

guarded_tools = guard_crew_tools(
    tools=my_crew_tools,
    guard_url="http://localhost:8080/",
    agent_id="crew-agent",
)

Hooks both run and _run (CrewAI calls _run internally).

browser-use

from vanzik.adapters.browseruse import GuardedBrowser

browser = GuardedBrowser(guard_url="http://localhost:8080/")

if browser.check_navigation("https://example.com/").allowed:
    await page.goto("https://example.com/")

# Or wrap the page directly so its action methods enforce policy for you:
guarded_page = browser.wrap_page(page)
await guarded_page.goto("https://example.com/")   # raises PermissionError on deny/approval

wrap_page gates 14 page methods: goto, click, fill, type, press, select_option, check, uncheck, evaluate, evaluate_handle, set_extra_http_headers, route, expose_function and add_init_script. fill and type use the data scope. Only read-only attributes such as url, title and content pass through; anything else raises AttributeError. See ADAPTERS.md.

MCP

from vanzik.adapters.mcp import GuardedMCPServer

server = GuardedMCPServer(guard_url="http://localhost:8080/")
server.add_tool("my_tool", "Description", handler=my_handler)
server.run()   # stdio JSON-RPC MCP server; pins MCP_PROTOCOL_VERSION

Or as a drop-in stdio server:

python -m vanzik.adapters.mcp --guard-url http://localhost:8080

OpenAI Agents SDK

from agents import Agent, Runner, function_tool
from vanzik import VanzikDenied, Guard
from vanzik.adapters.openai_agents import guard_tools

@function_tool
def run_shell(command: str) -> str:
    ...

guard = Guard("http://localhost:8080/", agent_id="ops-agent")
agent = Agent(name="ops", tools=guard_tools([run_shell], guard))

try:
    result = await Runner.run(agent, "clean up the build directory")
except VanzikDenied as e:
    print("blocked:", e.result.reason)

guard_tools returns gated copies of the FunctionTools; DENY and REQUIRE_APPROVAL raise out of Runner.run before the tool runs. To let the model see the reason and continue instead, attach vanzik_tool_guardrail(guard) as a tool input guardrail. Hosted tools (WebSearchTool, ...) cannot be gated. Runnable example: examples/openai-agents-config.py.

API reference (summary)

Guard(base_url="", agent_id="", timeout=5, api_key="", fail_mode="deny", tenant_id=None, parent_session_id=None)

Method Behavior
check(scope, *, action, command, path, domain, url, session_id, est_cost, meta, approval_id, parent_session_id) POST /v1/check (approval_id replays a resolved approval — see the quick start). Returns CheckResult. Transport failure → fail-closed DENY (or ALLOW if fail_mode="allow").
approve(id) / deny(id) POST /v1/approve/{id} / /v1/deny/{id}. Returns bool success. Sends Bearer if api_key set.
wait_for_approval(id, timeout=300, poll_interval=2) Polls GET /v1/status/{id} until resolved or deadline. Timeout → CheckResult(DENY, "Approval timed out").

CheckResult

Fields: decision, reason, matched_rule, approval_id, approval_url. Properties: .allowed, .denied, .needs_approval.

Exception hierarchy (all extend PermissionError)

  • VanzikError — base; carries .result: CheckResult.
  • VanzikDenied — policy said DENY.
  • VanzikApprovalRequired — policy said REQUIRE_APPROVAL and the decorator was not configured to wait. Carries .approval_id, .approval_url.
  • VanzikApprovalTimeout — wait_for_approval deadline elapsed. Carries .approval_id.
  • VanzikAuthError — a wait_for_approval status poll got 401/403 (API key missing or wrong). Carries .status.

License

Apache 2.0

Metadata

Release files for vanzik 2.0.0

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

Source distribution (sdist)

Source distribution for vanzik 2.0.0
File Size Uploaded Provenance Actions
vanzik-2.0.0.tar.gz 104.0 kB With provenance Details for vanzik-2.0.0.tar.gz

Built distribution (wheel)

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

Total release size: 150.7 kB

Release files / vanzik-2.0.0.tar.gz

Download URL vanzik-2.0.0.tar.gz
Size 104.0 kB
Tags Source
SHA-256 checksum
How to use checksums
206341c2c4cdb963f0e31276ef6e6e81f6d86f2449c23f7504820ab0e038b4b0
BLAKE2b-256 checksum
How to use checksums
3247e43b031871f320f4e04a60051f79ff5bcd3091cd4a2bf57ebdc7d4c41262
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / vanzik-2.0.0-py3-none-any.whl

Download URL vanzik-2.0.0-py3-none-any.whl
Size 46.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
483ee8a89f36724038a73009ae227498fcf590a531820cb61ad04e840851d312
BLAKE2b-256 checksum
How to use checksums
16f7730b16814ffab74114cfb00a1763f625a194f827383909c92fa4bf17f303
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for vanzik 2.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for vanzik-2.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.0.0 This release

2 release files Full provenance

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