<h1 align="center">Immunity Agent</h1>

<h3 align="center">Runtime security for AI coding agents. Policy enforcement, secret prevention,<br>supply chain blocking, and secret cleanup in one package.</h3>

<p align="center">
  <a href="https://pypi.org/project/immunity-agent/"><img src="https://img.shields.io/pypi/v/immunity-agent" alt="PyPI"/></a>
  <a href="https://github.com/PrismorSec/prismor/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License" /></a>
  <a href="https://github.com/PrismorSec/prismor"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" /></a>
  <a href="https://x.com/prismor_dev"><img src="https://img.shields.io/badge/@prismor__dev-black?logo=x&logoColor=white" alt="X" /></a>
  <a href="https://deepwiki.com/PrismorSec/prismor"><img src="https://img.shields.io/badge/DeepWiki-prismor-blue?logo=bookstack&logoColor=white" alt="DeepWiki" /></a>
  <a href="https://discord.gg/UtfVTWGY"><img src="https://img.shields.io/badge/Discord-join-5865F2?logo=discord&logoColor=white" alt="Discord" /></a>
</p>

<p align="center">
  <a href="https://prismor.dev">Website</a> &middot;
  <a href="docs/warden.md">Warden</a> &middot;
  <a href="docs/supply-chain.md">Supply Chain</a> &middot;
  <a href="docs/sweep-and-cloak.md">Sweep & Cloak</a>
</p>

---

<p align="center">
  <img src="assets/prismor-cli-demo.gif" alt="Prismor CLI Demo" width="820" />
</p>

---

## The Problem

AI coding agents execute shell commands, read and write files, access credentials, and call external APIs. They do this autonomously, often across many steps, with limited checkpoints.

This creates risks that traditional security tooling isn't designed for:

- **Prompt injection** - malicious content in a file, issue, or web page can redirect the agent mid-task
- **Unintended destructive actions** - an agent misinterprets an instruction and runs something irreversible
- **Secret exfiltration** - an agent reads `.env` or credential files as part of a debugging task and sends the content outbound
- **Privilege escalation** - an agent modifies sudoers, CI pipelines, or file permissions to resolve a permission error
- **Dependency manipulation** - an agent installs or rewrites a package at the direction of injected input

Standard OS-level and endpoint security tools monitor the kernel and filesystem. By the time they see an action, the agent has already decided to take it. The gap is at the agent layer.

---

## Capabilities

![Immunity Agent Architecture](assets/immunity-highlevel.png)

- 🛡️ [Warden](docs/warden.md) covers the policy engine, session logs, security audit, and CLI reference
- 📦 [Supply Chain](docs/supply-chain.md) covers install-time enforcement, IOC matching, and risk scoring
- 🛜 [Network Isolation](docs/network-isolation.md) covers egress allowlists, raw IP detection, and tunnel blocking
- 🔍 [Skill Scanner](docs/skill-scanner.md) covers MCP server and skill risk scanning across supported agents
- 🔐 [Sweep and Cloak](docs/sweep-and-cloak.md) covers secret prevention at tool boundaries and cleanup for leaked secrets - see [Using Cloak](docs/using-cloak.md) for the practical setup, best practices, and threat model
- 🐳 [Docker and Containers](docs/docker.md) covers container hardening, prerequisites, and known limitations

These capabilities map to the [OWASP Top 10 for LLM Applications](https://genai.owasp.org/llm-top-10/) - covering prompt injection (LLM01), sensitive information disclosure (LLM02), supply chain (LLM03), improper output handling (LLM05), and excessive agency (LLM06).

---

## Benchmarks

Measured overhead is 0.8 ms per tool call across 10,000 simulated agent sessions, below the 1 ms threshold for every task category tested.

![Warden Simulation Results](assets/warden-simulation.png)

See [benchmark.md](benchmark.md) for the full methodology, per-category breakdown, and latency analysis.

---

## Quick Start

**Option A — pip (recommended):**

```bash
pip install immunity-agent
warden setup          # interactive 5-step onboarding wizard
```

`warden setup` lets you pick enforcement mode, toggle detection rules, select agents, and optionally enable secret cloaking. Pass `--non-interactive` to skip the TUI.

**Option B — git clone + wizard:**

```bash
pip3 install pyyaml                          # required dependency
git clone https://github.com/PrismorSec/immunity-agent.git ~/.prismor
PRISMOR_MODE=enforce PRISMOR_CLOAK=1 bash ~/.prismor/scripts/init.sh .
```

This installs enforce-mode Warden hooks and the Cloak prevention layer. To register a secret, run `warden cloak add stripe_key` and enter the value when prompted. Reference it in tool calls as `@@SECRET:stripe_key@@` and the hook handles the rest.

Prefer the interactive wizard? Drop the env vars:

```bash
bash ~/.prismor/scripts/init.sh .
```

### Warden Modes

Warden runs in two modes, set via the `--mode` flag or the `PRISMOR_MODE` env var:

| Mode | Behavior |
|---|---|
| `observe` (default) | Logs all tool calls and findings. Never blocks. Safe for onboarding and auditing. |
| `enforce` | Blocks dangerous actions in real time before the agent executes them. |

Switch modes at any time by re-running the hook installer:

```bash
warden install-hooks --agent all --mode observe    # log only
warden install-hooks --agent all --mode enforce    # block dangerous actions
```

---

## Self-Hosted Dashboard

Warden includes a built-in web dashboard that visualizes session data from your local workspace DBs. No cloud, no external services - everything runs on your machine.

```bash
python3 warden/cli.py serve            # http://127.0.0.1:7070
python3 warden/cli.py serve --port 8080   # custom port
```

Open the URL in your browser. The dashboard polls `/api/stats` every 30 seconds and displays:

- **KPIs** — active sessions, tool calls inspected, dangerous commands prevented (24h)
- **Threats by category** — donut chart across 6 threat classes
- **Block rate** — 30-day timeseries of intercepted vs passed events
- **Agent breakdown** — blocked commands per agent (Claude Code, Cursor, Codex, etc.)
- **Tool call breakdown** — event counts by tool type
- **Top MCP & Skills** — most active MCP servers and skills with block counts
- **Threat patterns** — recurring findings ranked by frequency
- **Live event feed** — latest events with verdict and severity

The server reads from all workspaces registered via `warden install-hooks`. If no workspaces are registered yet, it starts with empty data.

![Self-Hosted Dashboard](assets/self-serve-img.png)

---

## How It Works

```mermaid
flowchart TD
    IDE["Your IDE / Agent\n(Claude Code · Cursor · Windsurf)"]

    IDE -->|"PreToolUse / PostToolUse hooks"| Warden

    subgraph Warden["Warden — Runtime Monitor"]
        Policy["Policy Engine\n(YAML rules)"]
        Session["Session Store\n(SQLite / JSONL)"]
        Policy --> Session
    end

    Warden -->|"action permitted"| Allow["ALLOW\n+ log event"]
    Warden -->|"rule matched"| Block["BLOCK\n+ log finding"]

    IDE -->|"PreToolUse hook\n(inject @@SECRET@@)"| Cloak
    IDE -->|"PostToolUse hook\n(scrub output)"| Cloak

    subgraph Cloak["Cloak — Secret Prevention"]
        Store["Secrets Store\n(~/.prismor/secrets/)"]
        Cloak_Hook["Substitute at\nexecution time"]
        Store --> Cloak_Hook
    end

    Sweep["Sweep — Secret Cleanup\n(scan & redact AI tool caches)"]
    IDE -.->|"offline scan"| Sweep

    IDE -->|"immunity npm/pip/cargo..."| SC

    subgraph SC["Supply Chain — Install Enforcement"]
        Scorer["Risk Scorer\n(age · maintainers · scripts)"]
        IOC["IOC Database\n(known compromised packages)"]
        Feed["Advisory Feed\n(Warden / NVD)"]
        Scorer --> IOC
        Scorer --> Feed
    end

    SC -->|"score < 30"| PkgMgr["Package Manager\n(npm · pip · cargo · go...)"]
    SC -->|"score >= 60 or IOC match"| SCBlock["BLOCK\n+ log to Warden store"]
```

---

## Supply Chain Enforcement

The `immunity` CLI wraps your package manager and evaluates every install against live threat intelligence before it runs. Unlike pnpm or other package managers, `immunity` is a security enforcement layer that scores packages on age, maintainer count, install scripts, and known IOCs, then blocks dangerous ones before they hit your disk. Ships with IOC coverage for the **mini-shai-hulud** attack (May 11 2026) and the **AntV hijacked-maintainer** attack (May 19 2026).

```bash
immunity npm install express                    # resolves cleanly, execs npm
immunity npm install @tanstack/react-router     # BLOCK — IOC match (score 100)
immunity pip install requests numpy             # resolves cleanly, execs pip
immunity pnpm add lodash
immunity uv add fastapi
immunity cargo add serde
```

Any command that isn't a recognised package install passes through transparently, so you can alias your package managers:

```bash
alias npm="python3 /path/to/immunity-agent/immunity npm"
alias pip="python3 /path/to/immunity-agent/immunity pip"
```

Verdicts are additive: `< 30` allow · `30–59` warn · `≥ 60` block. IOC matches force a block regardless of score. See [docs/supply-chain.md](docs/supply-chain.md) for the full scoring table, ecosystem support, and how to add new IOCs.

### `immunity harden` — close the bypass gap

Runtime scoring only fires when an install goes through `immunity`. A CI step, IDE plugin, or agent that ignores the alias bypasses it entirely. `immunity harden` is a static gate that writes `ignore-scripts`, `save-exact`, and pinned-fetch settings into `.npmrc` / `.yarnrc.yml` / `pip.conf` / `.cargo/config.toml` so the package manager itself enforces them — neutralising the `preinstall`/`postinstall` payload vector used by every recent npm supply chain attack (mini-shai-hulud, AntV, the mistralai/guardrails-ai PyPI wave).

```bash
immunity harden              # apply hardening to the current directory
immunity harden --dry-run    # preview without writing
```

Run it once at project bootstrap; existing keys are never overwritten.

---

## Contributing

PRs are welcome. Guidelines:

- New detection rules go in `warden/default_policy.yaml`, following the schema in `warden/policy_schema.json`
- Tests live in `tests/`, so run `pytest` before opening a PR
- Open an issue first if you're unsure where something fits

---

## Star History

<a href="https://www.star-history.com/?repos=PrismorSec%2Fprismor&type=date&legend=top-left">
 <picture>
   <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=PrismorSec/prismor&type=date&theme=dark&legend=top-left" />
   <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=PrismorSec/prismor&type=date&legend=top-left" />
   <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=PrismorSec/prismor&type=date&legend=top-left" />
 </picture>
</a>

---

- [Prismor.dev](https://prismor.dev)
