# AgentShield

> Security layer for AI agents: real-time interception of pip/npm/cargo/gem/go installs via Hermes & OpenClaw plugins, Claude Code/Codex hooks, MCP, shell guard, PATH shim, execve, and index proxy. Checks CVEs (OSV/NVD/GitHub), typosquats, malware, licenses, provenance, trust, lockfile hashes. Offline mirror, hash-chained audit, SBOM/SARIF.

- **Type:** MCP server
- **Install:** `agentstack add mcp-mkarvan-agentshield`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [mkarvan](https://agentstack.voostack.com/s/mkarvan)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [mkarvan](https://github.com/mkarvan)
- **Source:** https://github.com/mkarvan/AgentShield

## Install

```sh
agentstack add mcp-mkarvan-agentshield
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# AgentShield

**Security layer for AI agent frameworks.** AgentShield intercepts package installation requests made by AI agents, checks them against CVE databases and static analysis tools, enforces configurable response policies, and generates security posture reports — all locally, with no telemetry.

[](#installation)
[](LICENSE)
[](#)

> **AI agent?** Skip straight to the **[Agent Setup Guide](AGENT_SETUP.md)** — it has everything your agent needs to integrate AgentShield in one self-contained document.

---

## Why this exists

AI agents can now install arbitrary packages on behalf of users. This creates a novel attack surface that existing security tooling doesn't address:

- An agent can be **prompt-injected** — a malicious web page or tool result instructs the agent to install a backdoored package
- Agents may **typosquat** — suggest `requets` instead of `requests`, or `panda` instead of `pandas`
- Agents don't inherently **check CVEs** or audit dependency trees before installing
- Compromised packages can **exfiltrate context windows**, API keys, tool credentials, or local files before the user notices anything

AgentShield sits between the agent's intent ("install X") and the system executing that intent, providing a security checkpoint the agent cannot bypass. It works with any framework through native plugins (Hermes, OpenClaw) or the MCP protocol.

---

## Table of Contents

- [Architecture](#architecture)
- [Threat model](#threat-model)
- [Installation](#installation)
- [Quick start](#quick-start)
- [Configuration](#configuration)
- [CLI reference](#cli-reference)
  - [agentshield scan](#agentshield-scan)
  - [agentshield scan-file](#agentshield-scan-file)
  - [agentshield scan-mcp](#agentshield-scan-mcp)
  - [agentshield sbom](#agentshield-sbom)
  - [agentshield posture](#agentshield-posture)
  - [agentshield cache](#agentshield-cache)
  - [agentshield serve](#agentshield-serve)
  - [agentshield proxy](#agentshield-proxy)
  - [agentshield doctor / init](#agentshield-doctor--init)
- [Framework integrations](#framework-integrations)
- [Posture reports](#posture-reports)
- [Python API](#python-api)
- [Static analysis (--deep)](#static-analysis---deep)
- [Transitive dependency scanning](#transitive-dependency-scanning)
- [SBOM generation](#sbom-generation)
- [License compliance scanning](#license-compliance-scanning)
- [pre-commit hook](#pre-commit-hook)
- [GitHub Action](#github-action)
- [Drift detection](#drift-detection)
- [Rate limits](#rate-limits)
- [Diff scan mode](#diff-scan-mode)
- [Trust score / reputation system](#trust-score--reputation-system)
- [Container / Docker scanning](#container--docker-scanning)
- [HTTP daemon mode](#http-daemon-mode)
- [agentshield guard](#agentshield-guard)
- [Offline mode](#offline-mode)
- [Caching](#caching)
- [Audit log](#audit-log)
- [Provenance / attestations](#provenance--attestations)
- [SARIF output](#sarif-output)
- [Waivers](#waivers)
- [Notifications](#notifications)
- [Testing](#testing)
- [Contributing](#contributing)
- [License](#license)

---

## Architecture

```
┌───────────────────────────────── Entry points ─────────────────────────────────┐
│                                                                                 │
│  Agent plugins (in-process)     Agent hooks                Servers / CLI        │
│  ┌───────────────────────┐  ┌────────────────────┐  ┌─────────────────────────┐ │
│  │ Hermes  pre_tool_call │  │ Claude Code, Codex │  │ MCP (stdio) · HTTP :8765│ │
│  │ OpenClaw              │  │ PreToolUse         │  │ IPC socket · CLI / CI   │ │
│  │   before_tool_call    │  │ (agentshield hook) │  │ GitHub Action·pre-commit│ │
│  └───────────┬───────────┘  └─────────┬──────────┘  └────────────┬────────────┘ │
└──────────────┼────────────────────────┼──────────────────────────┼──────────────┘
               │                        │                          │
┌──────────────┴────────────────────────┴──────────────────────────┴──────────────┐
│                     Enforcement layers (all fail CLOSED)                        │
│    guard shell wrapper  ·  PATH shim  ·  execve interceptor (LD_PRELOAD/dyld)   │
│    index proxy :8799  —  PIP_INDEX_URL / npm registry / GOPROXY                 │
└──────────────────────────────────────┬──────────────────────────────────────────┘
                                       │ ScanRequest
                            ┌──────────▼──────────┐
                            │     Core Engine     │
                            │ denylist → allowlist│
                            │ → cache → rate limit│
                            └──────────┬──────────┘
                                       │ cache miss
         ┌─────────────────────────────┼─────────────────────────────┐
         │                             │                             │
┌────────▼─────────┐       ┌───────────▼───────────┐      ┌──────────▼──────────┐
│ Enrichment       │       │ Local heuristics      │      │ Static analysis     │
│ (parallel, fails │       │ (offline-capable)     │      │ (--deep only)       │
│  open)           │       │                       │      │                     │
│ • OSV            │       │ • typosquat (T1.2)    │      │ • semgrep           │
│ • NVD (CPE-      │       │ • malicious DB (T1.1) │      │ • bandit            │
│   version-aware) │       │ • prompt-inj. (T4.1)  │      │ • AST inspector     │
│ • GitHub Advisory│       │ • drift (D1.1)        │      │   (PyPI wheels/     │
│ • license (L1.1) │       │ • lockfile hashes     │      │    sdists) (T3.x)   │
│ • provenance     │       │   (H1.x)              │      └─────────────────────┘
│   (T6.x)         │       │ • syspkg CVEs (SP1.x) │
│ • trust score    │       └───────────────────────┘
│   (T5.1)         │
└──────────────────┘
         │
┌────────▼────────────────────────────────────────────────┐
│ Response Engine                                         │
│ severity policy → per-ecosystem → per-rule-ID → waivers │
│ ⇒ ALLOW · BLOCK · NEEDS_CONFIRMATION · LOG_ASYNC        │
└────────┬────────────────────────────────────────────────┘
         │ every decision
┌────────▼─────────────────────────┐   ┌──────────────────────────────────┐
│ Audit log — hash-chained JSONL   │   │ Local SQLite                     │
│ + SQLite query index             │   │ scan cache · CVE mirror ·        │
│ + HTTP/syslog forwarding         │   │ malicious DB · scan history ·    │
│ Webhook notifications (Slack)    │   │ provenance history · rate limits │
└──────────────────────────────────┘   └──────────────────────────────────┘
```

### Data flow

```
Agent: "pip install numpy==1.24.0"
  │
  ▼
[Entry point]  plugin hook / PreToolUse / guard / shim / execve / proxy / CLI
  └─→ ScanRequest(package="numpy", version="1.24.0", ecosystem="pypi")
        │
        ▼
  [Core Engine]
  ├── denylist  → BLOCK immediately (never scanned)
  ├── allowlist → ALLOW immediately (never scanned)
  ├── cache HIT → return cached ScanResult ( **Note:** PyPI publishing is planned for a future release.

### Optional extras

```bash
# Static analysis (semgrep + bandit) — needed for --deep flag
pip install "agentshield[static-analysis] @ git+https://github.com/mkarvan/AgentShield.git"

# Hermes Agent integration
pip install "agentshield[hermes] @ git+https://github.com/mkarvan/AgentShield.git"

# OpenClaw integration is a Node plugin (OpenClaw is TypeScript), installed in
# the OpenClaw box — not a Python extra:
#   openclaw plugins install @agentshield/openclaw-plugin
# (it shells out to the `agentshield` CLI, so install that too: pipx install agentshield)

# Hermes + static analysis (the [all] bundle)
pip install "agentshield[all] @ git+https://github.com/mkarvan/AgentShield.git"
```

---

## Quick start

```bash
# 1. Scan a package (online — hits OSV + NVD + GitHub Advisory)
agentshield scan requests==2.28.0 --ecosystem pypi

# 2. Deep scan — download wheel and run static analysis
agentshield scan some-new-package --ecosystem pypi --deep

# Scan package + its transitive dependencies
agentshield scan flask --transitive

# Scan an entire requirements.txt at once
agentshield scan-file requirements.txt

# Generate a CycloneDX SBOM from a manifest
agentshield sbom requirements.txt

# 3. Populate local database for offline use (~2–5 min first run)
agentshield cache warm

# 4. Generate a security posture report
agentshield posture

# 5. Start the MCP server (any MCP-compatible agent connects to this)
agentshield serve --mcp
```

**Exit codes for `agentshield scan`:** `0` = ALLOW/WARN/LOG_ASYNC, `1` = BLOCK.

### API keys (optional but recommended)

Set these to raise NVD rate limits and enable the GitHub Advisory Database:

```bash
export NVD_API_KEY=your-key-here     # 5 → 50 req/30s; get one at nvd.nist.gov/developers
export GITHUB_TOKEN=ghp_...          # enables GitHub Advisory lookups; any classic PAT works
```

You can also set them in `~/.config/agentshield/config.toml` under `[api]`.

---

## Configuration

AgentShield looks for config at `~/.config/agentshield/config.toml`. Create it to override defaults.

> [!IMPORTANT]
> **System-package CVE scanning is OFF by default (since v0.9.0).**
> AgentShield still *detects* system installs (`apt`/`yum`/`apk`/`brew`/`snap`/…) and prints an `SP1.1` warning, but it does **not** run a live CVE scan of them unless you opt in. This is deliberate: distro packages ship with many low/medium CVEs, so scanning every `apt-get install curl` or `yum install httpd` would block or nag on routine installs (and slow paths like `snap install` could time out).
>
> To turn it on, add three lines to your config:
>
> ```toml
> [syspkg]
> cve_scan = true        # default: false
> ```
>
> See [System package scanning (`[syspkg]`)](#system-package-scanning-syspkg) for the severity floor, findings cap, and recommended policy.

### Full config reference

```toml
# ── Response defaults (by severity) ──────────────────────────────────────────
[defaults]
critical = "block"        # ALLOW | BLOCK | WARN_CONFIRM | ASYNC_REPORT
high     = "warn_confirm"
medium   = "async_report"
low      = "ignore"
info     = "ignore"

# ── Per-ecosystem overrides ───────────────────────────────────────────────────
[ecosystems.pypi]
high = "block"            # Stricter than default for pip installs

[ecosystems.npm]
high     = "warn_confirm"
critical = "block"

[ecosystems.cargo]
critical = "block"
high     = "warn_confirm"

# ── Per-rule-ID overrides (highest priority) ──────────────────────────────────
[rules]
  [rules."T1.1"]    # Known-malicious: always block, regardless of severity
  mode = "block"

  [rules."T1.2"]    # Typosquatting: always block
  mode = "block"

  [rules."T2.3"]    # Transitive CVEs: only log, don't block
  mode = "async_report"

  [rules."T3.1"]    # Shell execution at install time
  mode = "warn_confirm"

  [rules."T3.5"]    # Credential harvesting: block
  mode = "block"

  [rules."T4.1"]    # Prompt injection heuristic: confirm before allowing
  mode = "warn_confirm"

# ── Allowlist / denylist ─────────────────────────────────────────────────────
[allowlist]
# Packages that bypass all checks (trusted internal packages, etc.)
packages = ["numpy", "requests", "pytest", "boto3"]

[denylist]
# Packages that are always blocked regardless of findings
packages = ["malicious-pkg-example", "colouredlogs"]

# ── API keys ─────────────────────────────────────────────────────────────────
[api]
# Also accepted via environment variables NVD_API_KEY and GITHUB_TOKEN
nvd_api_key  = ""    # Increases NVD rate limit from 5→50 req/30s
github_token = ""    # Required for GitHub Advisory Database (GraphQL)

# ── Cache settings ────────────────────────────────────────────────────────────
[cache]
db_path   = "~/.agentshield/agentshield.db"
ttl_hours = 24
# Entries are evicted (oldest first) once this many are cached, and each is
# re-fetched after ttl_hours. Never-expiring BLOCK entries are exempt from
# eviction. Entries are small JSON blobs, so the default 50,000-entry cap
# corresponds to roughly tens of MB of disk and working memory.
max_entries = 50000
# Warm-data freshness: offline scans and `cache stats` warn when the OSV
# mirror (populated by `agentshield cache warm`) is older than this.
warm_max_age_days = 7
# Opt-in: long-running `agentshield serve` daemons re-warm stale ecosystems
# in the background, checking every auto_warm_interval_hours.
auto_warm = false
auto_warm_interval_hours = 24

# ── System packages (apt/yum/apk/brew/snap/…) ─────────────────────────────────
[syspkg]
enabled  = true        # Detect system installs + emit SP1.1 warning (never blocks)
cve_scan = false       # OPT-IN live CVE scan of system packages (off by default)
severity_floor = "HIGH"  # When cve_scan is on, ignore findings below this severity
max_findings   = 50      # Cap findings shown; overflow summarised as "+N more"

  # Only applies when cve_scan = true.
  [syspkg.severity_policy]
  critical = "block"
  high     = "warn_confirm"
  medium   = "async_report"
  low      = "ignore"
  info     = "ignore"

# ── Release-age quarantine (A1.1) ─────────────────────────────────────────────
[release_age]
min_days = 0           # quarantine versions younger than N days; 0 = disabled
                       # (HIGH → warn_confirm under the default policy)

# ── Dependency-confusion protection (DC1.1) ───────────────────────────────────
[namespaces]
internal = []          # e.g. ["mycorp-*", "@mycorp/*"] — internal names that
                       # must NEVER resolve from a public registry (hard BLOCK,
                       # checked before the allowlist)

# ── Reporting ─────────────────────────────────────────────────────────────────
[reporting]
report_dir          = "~/.agentshield/reports/"
auto_report_on_exit = true

# ── License policy (opt-in) ───────────────────────────────────────────────────
[license_policy]
mode   = "disabled"    # disabled | denylist | allowlist | permissive-only
denied = ["GPL-2.0-only", "GPL-2.0-or-later", "GPL-3.0-only", "GPL-3.0-or-later",
          "AGPL-3.0-only", "AGPL-3.0-or-later", "SSPL-1.0", "EUPL-1.1", "OSL-3.0"]
# allowed = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC"]
```

### Response modes

| Mode | CLI identifier | Behaviour |
|------|---------------|-----------|
| Block | `block` | Refuse install. Returns error to agent. Agent cannot proceed. |
| Warn & confirm | `warn_confirm` | Present findings to user. Require explicit approval before allowing. Agent pauses. |
| Async report | `async_report` | Allow install unconditionally. Record findings for the next `posture` report. |
| Ignore | `ignore` | Skip this check entirely. No scan overhead. |

### Priority resolution

When a finding arrives, AgentShield looks up the response mode in this order (first match wins):

```
1. rule-level override      [rules."T1.2"] mode = "block"
2. ecosystem-level override [ecosystems.pypi] high = "block"
3. global severity default  [defaults] high = "warn_confirm"
   │
   (denylist check: always BLOCK regardless of above)
   (namespace check: internal names always BLOCK — even if allowlisted)
   (allowlist check: always ALLOW, skips the scan entirely)
```

### API keys

| Key | Where | Effect |
|-----|-------|--------|
| `NVD_API_KEY` | env var or `[api]` | NVD rate limit: 5 req/30s → 50 req/30s. Get one at [nvd.nist.gov/developers](https://nvd.nist.gov/developers/request-an-api-key) |
| `GITHUB_TOKEN` | env var or `[api]` | Enables GitHub Advisory Database. Any classic PAT with no scopes works. [github.com/settings/tokens](https://github.com/settings/tokens) |

AgentShield works without either key — OSV has no rate limit and covers most PyPI/npm/Rust packages.

### System package scanning (`[syspkg]`)

AgentShield also notices when an agent shells out to a **system** package manager (`apt`/`apt-get`, `yum`/`dnf`, `apk`, `brew`, `snap`, `pacman`, `zypper`, `flatpak`, …). This is controlled by the `[syspkg]` section:

| Key | Default | Eff

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [mkarvan](https://github.com/mkarvan)
- **Source:** [mkarvan/AgentShield](https://github.com/mkarvan/AgentShield)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** yes
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-mkarvan-agentshield
- Seller: https://agentstack.voostack.com/s/mkarvan
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
