ZIRAN
ZIRAN finds the vulnerabilities in AI agents that come from tools combining, not from any single prompt.
Docs · Examples · PyPI · Issues
pip install ziran
Take a Claude Code subagent that can read files and fetch URLs. Nothing in it looks wrong on its own:
---
name: researcher
description: Reads project files and looks things up on the web.
tools: Read, WebFetch
---
Answer questions about this repository. Read the relevant files, and fetch
documentation from the web when a library is unfamiliar.
Audit the directory it lives in (examples/24-claude-code-agent-audit/, no API key, no LLM call):
$ ziran audit agents/
╭─────── Static Analysis ───────╮
│ Found 2 issue(s) in 1 file(s) │
│ Critical: 1 High: 1 │
╰───────────────────────────────╯
┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Check ┃ Severity ┃ Message ┃ Location ┃
┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━┩
│ SA003 │ high │ Agent 'researcher' is granted dangerous tool 'WebFetch' │ agents/researcher.md:4 │
├────────┼────────────┼────────────────────────────────────────────────────────────┼────────────────────────┤
│ CC001 │ critical │ Agent 'researcher': data_exfiltration via Read -> WebFetch │ agents/researcher.md:4 │
└────────┴────────────┴────────────────────────────────────────────────────────────┴────────────────────────┘
Recommendations:
CC001: Remove one tool of the chain from the agent's 'tools' list, or split the agent.
SA003: Remove the tool or scope it with a permission rule, e.g. Bash(npm test:*).
FAILED — critical issues found
What just happened. ZIRAN mapped each declared tool to a capability (Read is read_file, WebFetch is http_request), put them in a graph and walked the edges against its library of dangerous chain patterns. read_file -> http_request matches a data exfiltration path: a prompt injection in any file the agent reads can tell it to send that file, or your .env, to a URL of the attacker's choosing. Neither tool trips a per-tool check, which is why list-based scanners report this agent as clean. The same analysis runs on LangChain, CrewAI, MCP and A2A agents, and on live agents over HTTPS, where ZIRAN also attacks the chain it found.
Auditing a whole plugin, gating CI on an allowlist baseline, scoring hook traces and checking its MCP servers: see the Claude Code guide and examples/25-claude-code-plugin/.
How it works
Five stages. DISCOVER probes tools, permissions and data access. MAP builds a NetworkX graph of capabilities. ANALYZE walks the graph against 30+ dangerous-chain patterns (the example above stops here). ATTACK runs an 8-phase campaign (reconnaissance, trust building, capability mapping, vulnerability discovery, exploitation setup, execution, persistence, exfiltration) where the live graph picks the next phase, so a critical chain found mid-campaign routes straight to exploitation and phases the graph shows to be pointless are skipped. REPORT emits scored findings with remediation guidance.
Two more things ZIRAN checks that text-only scanners cannot:
- Side effects at the execution layer. An agent can answer "I can't do that" and still fire
delete_user(id=42)underneath. ZIRAN intercepts the tool call, not the chat reply. - Trust between agents. In supervisor, router and peer-to-peer systems, an agent that accepts peer messages without validation is a lateral movement path.
Campaign strategies: fixed (sequential, reproducible for CI), adaptive (rule-based reordering) and llm-adaptive (an LLM reads the graph after each phase and plans the next). See adaptive campaigns.
How it compares
| Capability | ZIRAN | Promptfoo | Invariant (Snyk) | Garak | PyRIT | Inspect AI |
|---|---|---|---|---|---|---|
| Tool chain discovery (graph-based) | Yes | -- | Policy-based | -- | -- | -- |
| Side-effect detection (execution-level) | Yes | -- | Trace-based | -- | -- | Sandbox |
| Multi-phase campaigns w/ graph feedback | Yes | Turn-level | Flow analysis | -- | Composable | Multi-turn |
| Autonomous pentesting agent | Yes | -- | -- | -- | -- | -- |
| Multi-agent coordination | Yes | -- | -- | -- | -- | -- |
| Knowledge graph tracking | Yes | -- | Policy lang. | -- | -- | -- |
| Agent-aware (tools + memory) | Yes | Partial | Yes | -- | -- | Partial |
| A2A protocol support | Yes | -- | -- | -- | -- | -- |
| MCP protocol support | Yes | Partial | Yes | -- | -- | -- |
| Encoding/obfuscation attacks | Yes (8) | Yes (12+) | -- | -- | -- | -- |
| Industry compliance plugins | -- | Yes (46) | -- | -- | -- | -- |
| Streaming (SSE/WebSocket) | Yes | -- | -- | -- | -- | -- |
| CI/CD quality gate | Yes | Yes | -- | -- | -- | -- |
| Open source | Apache-2.0 | MIT | Partial | Apache-2.0 | MIT | MIT |
ZIRAN is not an LLM safety or alignment tool (use Promptfoo or Garak for jailbreak breadth and compliance), not a runtime guardrail (NeMo Guardrails, Lakera Guard, LLM Guard), and not a general eval framework (Inspect AI, Deepeval). It sits next to them: Promptfoo or Garak for attack breadth, ZIRAN for agent depth; guardrails at runtime, ZIRAN before deploy; Langfuse or LangSmith for traces, ZIRAN analyze-traces to score them. Full mapping in the Agent Security Landscape.
Benchmarks
639 attack vectors in 11 categories. 10/10 OWASP LLM Top 10 categories, 72/86 MITRE ATLAS techniques (14/14 agent-specific), measured against 20 published benchmarks. Numbers, per-benchmark tables and open gaps: benchmarks/ and the coverage comparison.
Install
pip install ziran
# with framework adapters
pip install ziran[langchain] # LangChain support
pip install ziran[crewai] # CrewAI support
pip install ziran[a2a] # A2A protocol support
pip install ziran[streaming] # SSE/WebSocket streaming
pip install ziran[pentest] # autonomous pentesting agent
pip install ziran[otel] # OpenTelemetry tracing
pip install ziran[ui] # web dashboard
pip install ziran[all] # everything
Quick start
CLI
# audit agent source or Claude Code agents, no LLM needed
ziran audit ./agents/
# scan a LangChain agent (in-process)
ziran scan --framework langchain --agent-path my_agent.py
# scan a remote agent over HTTPS
ziran scan --target target.yaml
# adaptive campaign with LLM-driven strategy
ziran scan --target target.yaml --strategy llm-adaptive
# stream responses in real time
ziran scan --target target.yaml --streaming
# encoding bypass variants (Base64 + ROT13)
ziran scan --target target.yaml --encoding base64 --encoding rot13
# scan a multi-agent system
ziran multi-agent-scan --target target.yaml
# discover capabilities of a remote agent
ziran discover --target target.yaml
# autonomous pentesting agent, optionally interactive
ziran pentest --target target.yaml [--interactive]
# view the interactive HTML report
open reports/campaign_*_report.html
Python API
import asyncio
from ziran.application.agent_scanner.scanner import AgentScanner
from ziran.application.attacks.library import AttackLibrary
from ziran.infrastructure.adapters.langchain_adapter import LangChainAdapter
adapter = LangChainAdapter(agent=your_agent)
scanner = AgentScanner(adapter=adapter, attack_library=AttackLibrary())
result = asyncio.run(scanner.run_campaign())
print(f"Vulnerabilities found: {result.total_vulnerabilities}")
print(f"Dangerous tool chains: {len(result.dangerous_tool_chains)}")
See examples/ for runnable demos, from static analysis to autonomous pentesting.
Remote agents
Any published agent over HTTPS, no source or in-process access required:
# target.yaml
name: my-agent
url: https://agent.example.com
protocol: auto # auto | rest | openai | mcp | a2a
auth:
type: bearer
token_env: AGENT_API_KEY
tls:
verify: true
protocol: auto probes for OpenAI-compatible chat completions, MCP (JSON-RPC 2.0) and A2A (/.well-known/agent.json) and falls back to REST. Ready-made targets in examples/15-remote-agent-scan/.
Web UI
pip install ziran[ui]
ziran ui # http://127.0.0.1:8484
docker compose up # same, at http://localhost:8484
Reports
HTML (interactive knowledge graph with attack paths highlighted), Markdown (CI-friendly summary tables) and JSON (machine-readable), generated on every run.
CI/CD
Use ZIRAN as a quality gate. Templates for GitHub Actions, GitLab CI, Jenkins, CircleCI and Azure Pipelines live in examples/07-cicd-quality-gate/; SARIF output lands in the GitHub Security tab or GitLab Security Dashboard.
# .github/workflows/security.yml
- uses: taoq-ai/ziran@v0
with:
command: ci
result-file: scan_results.json
severity-threshold: medium
sarif-output: results.sarif
Outputs: status (passed/failed), trust-score, total-findings, critical-findings, sarif-file. See the CI integrations guide.
Development
git clone https://github.com/taoq-ai/ziran.git && cd ziran
uv sync --group dev
uv run ruff check . # lint
uv run mypy ziran/ # type-check
uv run pytest --cov=ziran # test
Contributing
See CONTRIBUTING.md. Ways to help:
- Report bugs
- Request features
- Submit Skill CVEs for tool vulnerabilities
- Add attack vectors (YAML) or adapters
Citation
@software{ziran2026,
title = {ZIRAN: AI Agent Security Testing},
author = {{TaoQ AI} and Lage Perdigao, Leone},
year = {2026},
url = {https://github.com/taoq-ai/ziran},
license = {Apache-2.0},
version = {0.25.0}
}
License
Apache License 2.0. See NOTICE for third-party attributions.
Built by TaoQ AI
Metadata
Release files for ziran 0.41.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ziran-0.41.0.tar.gz | 4.8 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ziran-0.41.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 5.5 MB
Release files / ziran-0.41.0.tar.gz
| Download URL | ziran-0.41.0.tar.gz |
|---|---|
| Size | 4.8 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
26481be122a9da4e8ea8f185573382ad733d1f1a67bba1ca90d0f17f05afeb72
|
|
BLAKE2b-256 checksum How to use checksums |
1750ebc70b9dc50a29091da9924b847897a14d0077d91828d0be723a20d70323
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 3, 2026.
Transparency logRelease files / ziran-0.41.0-py3-none-any.whl
| Download URL | ziran-0.41.0-py3-none-any.whl |
|---|---|
| Size | 687.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
368e80e1c6458724a43e67b5e9b8d4b93691825d69c3e90ec94e9cc248247386
|
|
BLAKE2b-256 checksum How to use checksums |
648507e7e20c383ebc14d70053d321529a8bc6ad8979596a9b1ab5781acc959c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 3, 2026.
Transparency log