SkillAgentSearch skills...

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.

Install / Use

claude mcp add mkarvan -- npx -y github:mkarvan/AgentShield

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

74/100

Category

Security

Supported Platforms

Claude Code
Claude Desktop
OpenAI Codex
<p align="center"><img src="assets/agentshield-mascot.png" width="320" alt="AgentShield mascot"></p>

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.

Python 3.11+ License: MIT v0.14.0

AI agent? Skip straight to the Agent Setup Guide — 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

┌───────────────────────────────── 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 (< 5 ms; BLOCK verdicts never expire)
  └── cache MISS →
        ├── [Rate limits]   packages/hour + per-session wheel budget (R1.1)
        ├── [Enrichment ∥]  OSV + NVD + GitHub Advisory — version-filtered when
        │                   pinned — plus license policy (L1.1), provenance
        │                   attestations (T6.x), trust score (T5.1)
        ├── [Typosquat]     Levenshtein vs. top-N package list (T1.2)
        ├── [Malicious]     curated DB + warmed OSV malicious feed (T1.1)
        ├── [T4.1]          prompt-injection heuristic on context_hint
        ├── [--deep]        download wheel → semgrep + bandit + AST (T3.x)
        ├── [Drift]         decision regressed since last scan? (D1.1)
        └── [--verify-hashes, scan-file]  recorded lockfile hashes vs.
                            live registry digests (H1.x)
              │
              ▼
        [Response Engine]  severity policy → ecosystem → rule overrides
              │            → waivers (time-boxed, annotated, never silent)
        ┌─────┴──────┐
        │            │
     ALLOW        BLOCK / NEEDS_CONFIRMATION / LOG_ASYNC
        │            │
        └─────┬──────┘
              ▼
  [Cache write]  severity-based TTL (3 h critical → 7 d clean);
              │  BLOCK cached with no expiry (never silently flips to ALLOW)
              ▼
  [Audit log]  hash-chained record for EVERY decision — including
              │  short-circuits and cache hits (+ webhook notification)
              ▼
  [Entry point] → decision returned to the framework — fail closed on errors

Design principles

  • Local-first. The SQLite cache, CVE mirror, and malicious-package list are all on disk. Core scans work without network after cache warm. No telemetry, no cloud dependency.
  • Enrichment fails open; enforcement fails closed. When an enrichment source (OSV/NVD/GitHub) times out or errors, it's skipped and logged at WARNING — the scan continues with remaining sources. But the enforcement layers (hooks, guard, shim, execve, proxy) fail closed: a detected install that cannot be verified — unanalyzable arguments, an unsupported source, or a scanner error — is blocked, not allowed through.
  • Static analysis is opt-in. --deep downloads the wheel and runs semgrep/bandit. Default scans (CVE + typosquat) run in < 3 seconds without downloading anything.
  • Policy over hard-coding. Every response (block/warn/ignore/log) is driven by the config. You can tune per-severity, per-ecosystem, or per-rule-ID.

Threat model

Informed by "A Security Analysis of the OpenClaw AI Agent Framework" (arXiv 2603.27517), adapted for supply-chain attack vectors.

T1 — Supply Chain Attacks

| ID | Threat | Description | |----|--------|-------------| | T1.1 | Malicious package | Package exists solely to exfiltrate data or execute malicious code | | T1.2 | Typosquatting | Name is a near-miss of a legitimate package (reqests vs requests) | | T1.3 | Dependency confusion | Internal package name shadowed by a public registry package | | T1.4 | Compromised package | Legitimate package with a malicious version injected post-publish |

T2 — Known Vulnerabilities (CVEs)

| ID | Threat | Description | |----|--------|-------------| | T2.1 | Critical CVE | CVSS ≥ 9.0 in the requested version | | T2.2 | High CVE | CVSS 7.0–8.9 in the requested version | | T2.3 | Transitive CVE | Vulnerability in a dependency of the requested package | | T2.4 | Outdated package | Newer version available with security fixes |

T3 — Install-time Code Red Flags (--deep)

| ID | Threat | Detected by | |----|--------|-------------| | T3.1 | Shell execution | subprocess, exec, eval, os.system in setup.py | | T3.2 | Network at install time | urllib.request, requests, socket calls in setup.py | | T3.3 | Filesystem write outside package dir | Writes to ~/.ssh, ~/.aws, /etc at install | | T3.4 | Obfuscated code | exec(base64.b64decode(...)), marshal/zlib chains | | T3.5 | Credential harvesting | Reads *_KEY, *_TOKEN, *_SECRET env vars at install |

T4 — Agent-Specific Risks

| ID | Threat | Coverage | |----|--------|---------| | T4.1 | Prompt-injected install | Heuristic: flags package names in quoted/code-block patterns in context_hint | | T4.2 | Excessive tool permissions | Posture report: tool risk classification | | T4.3 | Context exfiltration risk | Posture report: sensitive env var detection |

Severity and response defaults

| Severity | CVSS range | Default response | |----------|-----------|-----------------| | CRITICAL | ≥ 9.0 | block | | HIGH | 7.0–8.9 | warn_confirm | | MEDIUM | 4.0–6.9 | async_report | |

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3
CategorySecurity
Updated1mo ago
Forks0

Languages

Python

Security Score

92/100

Audited on Jul 6, 2026

1 low