All-in-One Security. Offensive Security at the Core.
공격 보안·자동화·통합을 결합해 놓친 위협까지 탐지하는 올인원 보안 플랫폼
AI 에이전트가 밑으로 내려갈 수 없는 안전 바닥으로, 각 에이전트마다 정책을 적용하고 호출 결과를 커널이 보증하며 서명된 기록을 남긴다
A safety floor your AI agents can't get under: one policy for every agent, judged by what each call will run, backstopped by the kernel, with a signed record.
보안Rust · PythonGitHub @writ-agent온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기A safety floor your AI agents can't get under: one policy for Claude Code, Codex, Gemini CLI, Cursor, Windsurf and MCP, judged by what each call will run, backstopped by the kernel, with a signed, tamper-evident ledger.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Your agent asks. Your policy decides. The ledger remembers.
Watch it catch what command checks miss. claude-code#88462: an agent's cleanup script ran rm -rf "$HOME". provio refuses the script when it is written, refuses bash cleanup.sh by reading the script, and when the delete is obfuscated past every rule, the kernel boundary refuses it anyway. Reproduce it: examples/incident-88462.README 전문 보기 ↗Your agent asks. Your policy decides. The ledger remembers.
Website · Playground · Docs · Compare · Threat model · Changelog
Watch it catch what command checks miss. claude-code#88462: an agent's cleanup script ran rm -rf "$HOME". provio refuses the script when it is written, refuses bash cleanup.sh by reading the script, and when the delete is obfuscated past every rule, the kernel boundary refuses it anyway. Reproduce it: examples/incident-88462.
See it block an injected agent. A poisoned README tells the agent to read an SSH key, send it to attacker.example and rm -rf a directory; provio denies all three and the ledger proves it. Reproduce it offline: examples/attack-demo (scripted tool calls, real provio output).
A safety floor your AI agents can't get under. One policy for Claude Code,
Codex, Gemini CLI, Cursor, Windsurf, your SDK agents and your MCP servers,
checked before every tool call and judged by what the call will actually run
(the script behind bash cleanup.sh, a heredoc fed to a shell, the
package.json script behind npm run). Launched agents also run inside a
kernel write boundary for what no parser can see. Every decision lands in a
tamper-evident, signable ledger.
Built for developers who run agents in auto mode with real credentials, and for the platform teams who answer for what those agents did.
pip install provio # or: npm install -g provio
provio scan # what would provio have caught in your agents' last 30 days?
provio init # a policy (the disaster floor + secrets guard) and hooks
# for every agent found here: Claude Code, Codex, Gemini, Cursor, Windsurf
provio test "rm -rf ~" # try any command against your policy
provio scan reads the transcripts your agents already keep (Claude Code,
Codex, Gemini CLI) and replays every tool call through the policy. It
installs, hooks and records nothing, and --format markdown gives a
shareable summary with counts only. provio init never overwrites an existing
policy; --global wires your user-level agent config instead of one project.
The starter policy is default: allow plus two bundled packs, so agents stay
fast and only disasters stop them:
The floor pack refuses | and asks before |
|---|---|
recursive deletes of ~, /, C:\, your profile, ~/Documents … (also inside scripts, trap, sh -c, shutil.rmtree(Path.home())) | rm -rf ., .git, * |
mkfs, dd of=/dev/…, fork bombs, chmod -R 777 / | git reset --hard, clean -f, checkout -- . |
force pushes to main/master | DROP DATABASE, prisma migrate reset, Redis FLUSHALL |
| reading SSH private keys and cloud credentials | terraform destroy, gcloud projects delete, kubectl delete ns, aws s3 rm --recursive |
| reverse shells | curl … | sh |
the agent rewriting its own hooks or .provio/ ledger | edits to provio.yaml |
launching agents with --dangerously-skip-permissions, --yolo, --trust-all-tools | cron, launchd, scheduled tasks, shell-profile edits |
Add more with one line (packs: [floor, secrets-guard, github-safety, aws-safety]).
20 packs ship inside the binary: cloud CLIs (AWS, GCP, Azure), GitHub, databases,
Kubernetes, Terraform, Docker, hosting platforms, CI/CD config, package
publishing, Windows/macOS/Linux host security, internet exposure, MCP
destructive tools, outbound email/chat, payments; see packs/.
provio scan --packs all shows what all of them would have caught.
Prebuilt, signed binaries for Linux (x64, arm64, static), macOS (Apple silicon, Intel) and Windows (x64). Pick one:
pip install provio # Python users
npm install -g provio # Node users
curl -fsSL https://raw.githubusercontent.com/writ-agent/provio/main/scripts/install.sh | sh
irm https://raw.githubusercontent.com/writ-agent/provio/main/scripts/install.ps1 | iex # Windows PowerShell
brew install writ-agent/provio/provio # Homebrew (macOS, Linux)
scoop bucket add provio https://github.com/writ-agent/scoop-provio; scoop install provio # Scoop (Windows)
The install scripts check the binary against the release's checksums.txt
before installing it, and change nothing else (no PATH or profile edits).
or download provio-<target> from the
latest release
(checksums, Sigstore bundles and build provenance attached). Then
provio init in your project, or launch an agent inside the kernel boundary:
provio run -- claude
No daemon, no images, no account. The default backend is the host OS, and the
first run creates .provio/ledger.jsonl next to your policy. For a SQLite
ledger, build with --features sqlite and pass --ledger .provio/ledger.db.
Every integration goes through one decision point, provio check
(Contract 6): the agent sends a pending tool call, provio
evaluates provio.yaml, records the decision, and answers. No daemon; if provio
is missing or errors, the tool does not run.
| Agent | How | Per tool call |
|---|---|---|
| Claude Code | the plugin: /plugin marketplace add writ-agent/provio then /plugin install provio@provio (plugins/claude-code); or per project provio integrate claude-code (writes hooks into .claude/settings.json), or just provio run -- claude | yes — a provio ask becomes Claude Code's own permission prompt |
| OpenAI Codex CLI | provio integrate codex (.codex/config.toml), or provio run -- codex | yes |
| Gemini CLI | the extension: gemini extensions install https://github.com/writ-agent/provio; or per project provio integrate gemini (.gemini/settings.json), or provio run -- gemini | yes — a provio ask becomes Gemini's confirmation |
| Cursor | provio integrate cursor (.cursor/hooks.json), or provio run -- agent | yes (MCP asks use Cursor's prompt) |
| Windsurf | provio integrate windsurf (.devin/hooks.json) | yes (asks are denied) |
| LangGraph | provio_sdk.langgraph.provio_tool_node(tools, provio) | yes |
| OpenAI Agents SDK | provio_sdk.openai_agents.guard_agent(agent, provio) | yes |
| Claude Agent SDK (Python / TypeScript) | provio_sdk.claude_agent_sdk.provio_hooks(provio) / createProvioIntegration({ client }) | yes |
| Any MCP client | provio proxy --mcp --server <name> -- <server cmd> (stdio), or --transport http --upstream <url> for remote servers; tool definitions are pinned, so a changed one is held until you accept it |
# Claude Code, per project
provio integrate claude-code
# Python — extras: langgraph, openai-agents, claude-agent-sdk
pip install "provio-sdk[langgraph]"
# TypeScript / Node
npm install provio-sdk
Both SDKs bring the prebuilt provio binary with them (provio on PyPI,
provio on npm) — nothing else to install.
Package docs: Python · TypeScript · per-agent notes and residual risks: docs/integrations/.
provio uiprovio ui # opens http://127.0.0.1:<port> in your browser
A local web console for the policy file and ledger in front of you: connect
an agent (snippets filled in with your paths, and a live "connected" signal
from the ledger), watch every decision as it is recorded, approve or deny
ask calls (provio check --ask ui), edit and test the policy, and run
commands in the kernel sandbox to watch an escape attempt fail with the exact
OS error. Loopback only, token-gated, no external requests. See
docs/ui.md.
No install needed to try the policy language itself: the playground runs the real engine in your browser.
provio.yaml is the whole surface. Four verdicts, first match wins, unmatched
calls hit default.
version: 1
default: ask # --yolo flips this to allow. Nothing else does.
rules:
- id: block-destructive-shell
when: tool == "bash" and command matches "rm -rf|mkfs|dd if=|:\(\)\{"
verdict: deny
reason: "Destructive system command. Narrow the path and retry."
- id: protect-production-db
when: tool startswith "postgres" and query matches "(?i)(DROP|TRUNCATE|ALTER)"
verdict: ask
irreversible: true # excluded from automated replay
timeout: 5m
- id: egress-allowlist
when: tool == "http" and not url.host in hosts.allowed
verdict: deny
- id: mask-pii
when: tool startswith "postgres"
verdict: redact
patterns: ["[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"]
hosts:
allowed: [api.github.com, registry.npmjs.org, "*.internal.acme.com"]
A denial is not a dead end. The agent receives the rule id, the human reason and
the provio.yaml:6 that produced it, so it can correct itself instead of retrying
blind. The file lives in your repo, so the policy travels with the code and
reviews like code.
Start from a pack instead: provio policy add terraform-safety · k8s-prod ·
pii-redaction.
Some calls are only dangerous because of what came before them, so provio also judges the session, not just the call (session guards):
.env, cloud credentials or
an SSH key, a later call that can carry data off the machine asks first,
naming the file. That is the exfiltration leg of the "lethal trifecta",
which no single-call rule can see.call_budget: 300 caps the tool calls of an unattended
session.Logs are what an application chose to write. A ledger is evidence: every call, its verdict, the rule that decided it, who approved it, and the hash of the record before it.
Editing one line breaks the chain from that record onward, and provio verify
names the record it broke at. Nothing is captured beyond metadata and hashes
unless you turn content capture on, and Provio sends nothing anywhere — there is no
telemetry to opt out of.
your agent, unchanged Claude Code · Codex · LangGraph · your own loop
│
│ tool call intercepted
▼
┌─ provio ──────────────────────────────────────────────────────┐
│ 1 INTERCEPT mcp proxy · process wrap · sdk hook │
│ 2 DECIDE provio.yaml → allow · deny · ask · redact │
│ 3 RECORD hash-chained ledger + OTel GenAI span │
└─────────┬───────────────────────────────────────────────────┘
│ approved calls only
▼
sandbox backend (local-os · docker · …) · MCP servers
Provio wraps agents; it never asks you to adopt a runtime. The decision point is the same in all three interception modes, and so is the record.
provio run -- <agent> | wrap an agent process under policy |
provio proxy --mcp --server <name> -- <cmd> | govern every call to an MCP server |
provio log [--json] · provio show <call-id> | what did my agent actually do last night (--json: one session per line, for scripts) |
provio verify | is this ledger still the one that was written |
provio replay <session> --candidate <file> | what would this policy have done to last week's run |
provio policy test | unit-test rules against recorded fixtures |
provio doctor | what is governed, and what is blind |
provio report | one self-contained HTML file to hand to someone else |
provio mcp serve | provio as an MCP server: agents check a call, read decisions, verify the ledger (docs) |
Provio governs actions, not reasoning.
provio verify catches edited records and broken
links, but anyone with write access can rewrite the file and recompute the
chain. A signed receipt (provio receipt create) pins every record up to a
checkpoint, so a later edit, rewrite or truncation of those records fails
provio receipt verify for anyone holding the receipt and your public key;
anchoring it in the Sigstore Rekor public log (provio receipt anchor --to rekor)
adds an independent timestamp. Records after the latest receipt are still only
tamper-evident, and a stolen signing key or a host compromised before signing
defeats receipts. See docs/receipts.md.provio doctor, which says this out loud rather than scoring itself.Full residual-risk table: docs/THREAT_MODEL.md.
| Layer | Today | Next |
|---|---|---|
| Agents | Claude Code, Codex CLI, Gemini CLI, Cursor, Windsurf (hooks); LangGraph, OpenAI Agents SDK, Claude Agent SDK (Python + TypeScript); any MCP client; any process via run | more agent hook protocols as they are published |
| Interception | hook gateway (provio check), MCP proxy (stdio, Streamable HTTP / SSE), process wrap | — |
| Policy engines | native DSL, Rego, Cedar — one verdict IR, one fixture corpus | — |
| Sandbox backends | local-os with a kernel boundary (Landlock + seccomp · AppContainer + Job Object · Seatbelt), docker | microsandbox, e2b/firecracker, k8s |
| Ledger stores | JSONL (every platform), SQLite WAL (sqlite feature), Postgres (postgres feature); signed receipts with Rekor anchoring | object-store export |
| Platforms | macOS, Linux, Windows — CI builds all three | six release targets |
Pre-release. The core spine, all three policy engines, both workstation ledger stores and the kernel sandbox are built and tested on Linux, macOS and Windows in CI; the enterprise wave is in progress. Twelve crates, one frozen record schema.
| Wave | Scope | State |
|---|---|---|
| 0 | Frozen contracts, threat model, ADRs, CI | done |
| 1 | Native policy engine, ledger + verify, MCP stdio proxy, local-os sandbox, approval gate, CLI | done |
| 2 | doctor, report, replay trio, policy test, OTel spans, release pipeline | done |
| 2 | Kernel sandbox (Landlock/seccomp · AppContainer · Seatbelt), docker backend, SQLite ledger, benchmarks | done — confining provio run itself is open |
| 3 | Rego + Cedar | done |
| 3 | SDK hooks and the hook gateway | done |
| 3 | Postgres ledger, signed + anchored receipts, console (provio ui), Codex / Gemini / Cursor / Windsurf hooks, MCP over HTTP | done |
| 3 | Helm / SSO / RBAC / SIEM | not started |
| 4 | Fuzzing (running weekly), e2e matrix, published benchmarks, 1.0 | in progress |
provio doctor is the authority on what your build actually enforces. The plan and
its honest wave status live in
docs/internal/BUILD_PLAN.md.
| Path | What lives there |
|---|---|
crates/provio-core | Frozen contracts: call, verdict IR, ledger record, sandbox, approver, pipeline |
crates/provio-policy, -rego, -cedar | The three policy engines behind one PolicyEngine trait |
crates/provio-ledger | Hash chain, JSONL / SQLite / Postgres stores, verify |
crates/provio-receipts | Signed receipts, Merkle inclusion proofs, Rekor and file anchors |
crates/provio-sandbox, -docker | local-os kernel boundary and the docker backend |
crates/provio-mcp | MCP stdio proxy |
crates/provio-cli, provio-tui | The provio binary, its approval gate, and the provio ui console |
crates/provio-wasm | The engine compiled to WebAssembly for the playground |
crates/provio-replay, provio-otel | Trajectory replay and OpenTelemetry spans |
crates/provio-bench, fuzz/ | Criterion benches and cargo-fuzz targets (standalone crates) |
packs/, examples/ | Policy packs and example provio.yaml files |
adapters/python, adapters/typescript | provio-sdk (Python) and provio-sdk (TypeScript) integration packages |
deploy/ | GitHub Action, Helm chart, air-gap and Terraform notes |
docs/ | Policy reference, interfaces, threat model, ADRs — index |
site/ | The landing page and the playground |
DCO sign-off, no CLA. Security-path changes (policy, ledger, MCP, sandbox) get an adversarial review before merge. See CONTRIBUTING.md and docs/SECURITY.md.
Threat model · Policy reference · Interfaces · Decisions · Brand
Apache-2.0, permanently. PROVIO — Warranted Runtime for Intelligent Tools.
| every MCP tool call |
| Any other agent | provio run -- <agent>: kernel-confined launch; or call provio check from its hook system | launch, plus hooks where the agent has them |