
Self-hosted runtime control plane for AI agents. Observe or HITL approve or Block rogue tool calls before it executes: secret leaks, prompt injection, supply chain etc in a local dashboard. Agent agnostic (Claude, codex, langchain etc.)
Plus Grok Build, Crush, OpenHands, Qwen Code, Continue CLI, Goose, Hermes, OpenClaw, Devin CLI, Factory Droid, Aider, and more — see AGENT_INTEGRATIONS.md for the full coverage matrix
For the Skill, curl, and git-clone alternatives, plus PEP 668 systems and secret-cloaking setup, see the full installation guide.
tools/call is policy-evaluated before it forwards and each response is injection-scanned before the model sees it, so a poisoned tool result never becomes context. prismor mcp-gateway install moves an existing .mcp.json behind itprismor inference-hook serve, which runs your policy on the transcript and answers allow/deny before the model runs — signed requests (Standard Webhooks), fail-closed, shadow mode, nothing to install on user devices. prismor inference-hook test sends signed sample frames to check the wiring_meta, and prismor tags lists, tests, and lints the rule expressionsuse_subject("user:alice") and a multi-tenant agent gets per-user attribution, per-user IAM profiles, and per-user suspensionprismor allow makes narrow exceptions, and prismor unlock opens a password-gated, time-boxed window in which an agent may edit policy (never the self-protection rules that guard Prismor itself)prismor tokens breaking down where a session's context and token spend actually wentprismor doctor health-checks every subsystem (hooks, policy signature, enrollment, telemetry sink, chain state), and prismor pause / pause-hard suspends enforcement only for a human during an incident while observe-mode logging keeps runningprismor trail verify proves the history hasn't been edited, deleted, or rewrittenprismor attest verifyprismor discover and flags any AI agent running without Prismor hooks (shadow AI)prismor ingest --discover replays on-disk session transcripts through the live policy engine, so the dashboard is populated on day one and you can see exactly what flipping a rule to enforce would have blocked, plus --coverage for sessions that ran unmonitoredFull command map across every capability: CLI Reference.
These capabilities map to the OWASP Top 10 for LLM Applications - covering prompt injection (LLM01), sensitive information disclosure (LLM02), supply chain (LLM03), improper output handling (LLM05), and excessive agency (LLM06).
Real workflows with the commands and config that make them work — onboarding a team in observe mode, per-user IAM attribution for multi-agent and framework pipelines, shadow AI discovery, step-up approval for high-stakes operations, and generating a signed attestation bundle for a compliance audit. See USE_CASES.md.
prismor setup asks you to pick one posture instead of configuring six policy axes by hand. Each compiles into .prismor/policy.yaml — enforcement, egress, tool access, tag rules, sandbox and data boundary together.

| Mode | For | Coverage | Friction |
|---|---|---|---|
dev-safe | Feature work on code you haven't read | 31% | 9% |
trusted-workspace | Trusted internal repos, local Docker work | 34% | 9% |
regulated-airgap | PII/PHI, SOC 2, EU AI Act — no network, no shell | 100% | 90% |
prismor mode list # compare the three
prismor mode explain dev-safe # the trade, including what it does NOT stop
prismor mode apply dev-safe # compile it into this workspace
prismor mode apply regulated-airgap --observe # what it would block, blocking nothing
Every mode states its residual risk. Full breakdown: docs/modes.md.
Enforcement is decided per rule by your policy, not by a single global switch. Each rule carries a mode, and settings.default_mode (default observe) covers any rule that doesn't set one:
| Mode | Behavior |
|---|---|
observe (default) | Logs the tool call and the finding. Never blocks. Safe for onboarding and auditing. |
enforce | Blocks the action in real time before the agent executes it. |
Out of the box everything observes — nothing is blocked until you flip rules (or default_mode) to enforce in your policy:
# .prismor/policy.yaml
settings:
default_mode: observe # global default for rules without their own mode
rules:
- id: destructive-rm-rf
mode: enforce # this rule blocks; the rest still just observe
Policy is authoritative: a rule set to enforce blocks regardless of how the hook was installed (--mode), so an admin who flips a rule to enforce via the control plane blocks even on observe-installed devices. See Layered Policy & Exemptions for org / project / repo precedence and the non-overridable floor.
prismor setup makes the choice explicit rather than implied: an observe install ships with the defaults on, while an enforce install starts with nothing selected and asks you to pick what blocks (the safety floor is pre-marked recommended — press a to take it). Your selection is written to .prismor/policy.yaml as settings.selection: explicit plus one line per rule, so what blocks is readable in the file. When a rule then blocks something legitimate, the deny message prints the exact prismor allow <rule> --pattern '<literal>' that fixes it — for the human to run; agents are stopped from editing Prismor's own config by always-on self-protection rules, unless the human opens a short password-gated window with prismor unlock. See Choosing what blocks and Making exceptions.
The install flag still sets the starting posture, and an observe install combined with PRISMOR_LOCAL_DRY_RUN=1 acts as a local dry-run kill-switch that suppresses all blocking:
prismor install-hooks --agent all --mode observe # start in observe everywhere
prismor install-hooks --agent all --mode enforce # honor policy enforce rules
Upgrading from a pre-
moderelease? Backward compatibility is preserved: a policy that predates per-rule modes (it setssettings.block_categoriesbut nodefault_modeand no rule-levelmode) keeps its original behavior — those categories still block when installed with--mode enforce. The moment your policy adopts the per-rule model (anymode/default_mode), it becomes fully policy-authoritative as described above.
See the decision contract for the event shape and verdict vocabulary, and governance surfaces for which surface to use per agent.
Three modules from Capabilities, with setup, output, and results.
Disabled by default. See docs/semantic-guard.md for full setup.
See docs/supply-chain.md for the full scoring table, ecosystem support, and IOC format.
This does not affect policy rules set to mode: enforce in .prismor/policy.yaml — those remain policy-authoritative regardless of how the hook was installed (see Observe / Enforce above).
Scoped Agent synthesizes a per-session allowed_tools/deny_tools list at .prismor/scoped/{session_id}.json. This check is independent of hook --mode — a tool in deny_tools is hardcoded to action: block / mode: enforce in prismor/runtime/scoped_agent.py, so it blocks even when hooks are installed with --mode observe. Uninstalling hooks or switching to observe mode will not lift a scoped denial.
prismor scope list # find the session ID
prismor scope show ID # inspect its allowed_tools / deny_tools (`latest` works too)
prismor scope clear ID # remove the scoped rules for that session
prismor scope edit ID # or hand-edit deny_tools in $EDITOR
There's no bulk-clear — each session is cleared by ID individually. If a session was scoped before you ran scope clear, the cleanest fix is usually to start a fresh session rather than chase the existing one's cached state.
See benchmark.md for the full methodology, per-category breakdown, and latency analysis.
PRs are welcome. Read CONTRIBUTING.md before you start — it explains the one thing that matters most here: reuse the mechanisms that already exist, and solve the problem in the fewest lines you can. Smaller diffs get merged faster.
The short version:
prismor/runtime/default_policy.yaml, following the schema in prismor/runtime/policy_schema.json — detection patterns never go in Pythontests/ — run bash scripts/run_security_tests.sh before opening a PRBy participating you agree to the Code of Conduct.
| surface | what it governs | refuse | rewrite input | redact output |
|---|
| Coding-agent hooks | an agent's entire tool surface | yes | Claude/Qwen | no |
| MCP gateway | every MCP server behind one connector | yes | yes | yes |
| Mirrored built-ins | the agent's own Bash/Read/Write, over MCP | yes | yes | yes |
| Framework SDK adapters | in-process agents (13 frameworks) | yes | no | no |
prismor eval-server | non-Python callers, external proxies | yes | yes | yes |
| Inference-hook channel | hosted transcript-turn webhook | yes | no | no |
| Agent | Project scope | User scope |
|---|
| Claude Code | <workspace>/.claude/settings.json | ~/.claude/settings.json |
| Cursor | <workspace>/.cursor/hooks.json | ~/.cursor/hooks.json |
| Windsurf | <workspace>/.windsurf/hooks.json | ~/.codeium/windsurf/hooks.json |
| OpenClaw | <workspace>/.openclaw/plugins.json | ~/.openclaw/config.json |
| Hermes | <workspace>/.hermes/plugins.json | ~/.hermes/config.json |
| Codex | <workspace>/.codex/hooks.json | ~/.codex/hooks.json |
| Copilot | <workspace>/.github/copilot/hooks.json | ~/.copilot/hooks.json |
| Grok Build | <workspace>/.grok/hooks/prismor.json | ~/.grok/hooks/prismor.json |
| Kiro CLI | <workspace>/.kiro/agents/kiro_default.json | ~/.kiro/agents/kiro_default.json |
| Crush | <workspace>/crush.json | ~/.config/crush/crush.json |
| OpenHands | <workspace>/.openhands/hooks.json | ~/.openhands/hooks.json |
| Qwen Code | <workspace>/.qwen/settings.json | ~/.qwen/settings.json |
| Continue CLI | <workspace>/.continue/settings.json | ~/.continue/settings.json |
| Goose | <workspace>/.agents/plugins/prismor/hooks/hooks.json | ~/.agents/plugins/prismor/hooks/hooks.json |