Skip to content

brigen/agent-shield

Repository files navigation

AgentShield

A firewall and audit log for AI agents.

AgentShield sits between your AI agents and the tools they use. It intercepts every tool call, enforces allow/deny policies, rate-limits dangerous operations, and logs everything — so you know exactly what your agents are doing.

Works with Claude Code, Cursor, Windsurf, and any custom MCP-based agent.

You wouldn't deploy an API without rate limiting. Why are your agents different?


What It Does

┌─────────────┐     ┌──────────────────────────────────────────┐     ┌─────────────┐
│  AI Agent    │     │             AgentShield Proxy             │     │  MCP Server  │
│ (Claude Code │────▶│                                          │────▶│  (GitHub,    │
│  Cursor,     │◀────│  Intercept → Policy Check → Log → Route  │◀────│   Jira,      │
│  Custom)     │     │                                          │     │   Slack...)   │
└─────────────┘     └──────────────────────────────────────────┘     └─────────────┘
                              │           │           │
                              ▼           ▼           ▼
                         ┌────────┐ ┌─────────┐ ┌──────────┐
                         │ Policy │ │  Audit   │ │Dashboard │
                         │ Engine │ │   Log    │ │   API    │
                         └────────┘ └─────────┘ └──────────┘

Three interception layers:

  • MCP tool calls — intercept any MCP server (GitHub, Jira, Slack, filesystem, etc.)
  • CLI commands — intercept shell commands agents run (rm -rf, git push --force, etc.)
  • HTTP requests — intercept outbound HTTP (block exfil domains, scan for secret leaks)

Quick Start (5 minutes)

1. Install

npm install -g agent-shield

2. Create a policy file

Create agent-shield.yaml in your project root:

version: "1"

settings:
  log_level: "info"
  log_file: "./agent-shield-audit.log"
  redact_secrets: true

servers:
  - name: "github"
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_TOKEN: "${GITHUB_TOKEN}"

rules:
  # Block dangerous operations
  - name: "block-destructive-git"
    action: deny
    servers: ["github"]
    tools: ["push_files", "delete_branch", "delete_repository"]
    message: "Destructive git operations are blocked"

  # Rate limit writes to 20/min
  - name: "rate-limit-writes"
    action: allow
    tools: ["write_file"]
    rate_limit:
      max_calls: 20
      window_seconds: 60

  # Allow reads freely
  - name: "allow-reads"
    action: allow
    tools: ["read_file", "search_files", "list_directory"]

  # Log anything else for review
  - name: "warn-unknown"
    action: warn
    message: "Unrecognized tool — logged for review"

  # Block everything not matched above
  - name: "default-deny"
    action: deny
    message: "Not explicitly permitted by policy"

3. Validate your policy

agent-shield policy validate
# ✓ Policy is valid (5 rules loaded)

4. Connect your agent

Claude Code — update ~/.claude/config.json:

{
  "mcpServers": {
    "github": {
      "command": "agent-shield",
      "args": ["start", "--server", "github", "--config", "./agent-shield.yaml"]
    }
  }
}

Cursor — update .cursor/mcp.json:

{
  "mcpServers": {
    "github": {
      "command": "agent-shield",
      "args": ["start", "--server", "github", "--config", "./agent-shield.yaml"]
    }
  }
}

That's it. Every tool call now goes through AgentShield's policy engine.


Examples

Block an agent from deleting repos but allow reading issues

rules:
  - name: "block-destructive"
    action: deny
    tools: ["delete_repository", "delete_branch", "push_files"]
    message: "Destructive operations are not allowed"

  - name: "allow-read-ops"
    action: allow
    tools: ["get_issue", "search_issues", "list_repos", "read_file"]

  - name: "default-deny"
    action: deny
    message: "Not permitted"

Rate limit an agent to 10 file writes per minute

rules:
  - name: "rate-limit-writes"
    action: allow
    tools: ["write_file", "create_file"]
    rate_limit:
      max_calls: 10
      window_seconds: 60

  - name: "allow-reads"
    action: allow
    tools: ["read_file", "search_files"]

  - name: "default-deny"
    action: deny

Proxy multiple MCP servers with different policies

servers:
  - name: "github"
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_TOKEN: "${GITHUB_TOKEN}"

  - name: "filesystem"
    command: "npx"
    args: ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"]

  - name: "linear"
    url: "https://mcp.linear.app/sse"
    headers:
      Authorization: "Bearer ${LINEAR_TOKEN}"

rules:
  # GitHub: read-only
  - name: "github-read-only"
    action: deny
    servers: ["github"]
    tools: ["push_files", "create_branch", "delete_branch"]
    message: "GitHub is read-only through AgentShield"

  # Filesystem: allow reads, rate-limit writes
  - name: "fs-allow-reads"
    action: allow
    servers: ["filesystem"]
    tools: ["read_file", "list_directory", "search_files"]

  - name: "fs-limit-writes"
    action: allow
    servers: ["filesystem"]
    tools: ["write_file"]
    rate_limit:
      max_calls: 30
      window_seconds: 60

  # Linear: allow everything (trusted)
  - name: "linear-allow-all"
    action: allow
    servers: ["linear"]

  # Default deny
  - name: "default-deny"
    action: deny
    message: "Not explicitly permitted"

Match on tool arguments with regex

rules:
  # Block writes to production paths
  - name: "block-prod-writes"
    action: deny
    tools: ["write_file"]
    args_match:
      path: "/prod/|/production/"
    message: "Cannot write to production paths"

  # Allow writes elsewhere
  - name: "allow-writes"
    action: allow
    tools: ["write_file"]

Beyond MCP: CLI Command Interception

Agents don't just call MCP tools — they run shell commands too. AgentShield can intercept those as well.

Dry-run a command against policy

agent-shield exec --dry-run "rm -rf /"
# ✗ DENY: "rm -rf /" — Destructive file operations blocked (rule: block-destructive)

agent-shield exec --dry-run "git status"
# ✓ ALLOW: "git status" (rule: allow-safe-commands)

agent-shield exec --dry-run "docker run ubuntu"
# ⚠ WARN: "docker run ubuntu" — Docker command detected (rule: warn-docker)

Run a command through the policy engine

agent-shield exec "git status"    # runs if allowed
agent-shield exec "rm -rf /"     # blocked — exits with code 1

Claude Code hook integration

AgentShield can generate a Claude Code PreToolUse hook that automatically intercepts every Bash tool call:

# See the hook config
agent-shield hook show

# Test what the hook would do
agent-shield hook test "kubectl delete pod --all"

Add the output of agent-shield hook show to your .claude/settings.json and every shell command Claude Code runs will go through policy.

Default command rules block:

  • rm -rf, destructive filesystem ops
  • git push --force, git reset --hard
  • System commands (shutdown, dd, mkfs)
  • Data exfiltration via curl/wget

Beyond MCP: HTTP Request Interception

AgentShield can also act as an HTTP forward proxy — intercepting outbound requests, blocking dangerous domains, and scanning request bodies for leaked secrets.

Check a URL against policy

agent-shield http-check https://pastebin.com/raw/abc
# ✗ DENY — Request to known data exfiltration domain blocked

agent-shield http-check https://api.github.com/repos
# ✓ ALLOW (rule: allow-dev-domains)

agent-shield http-check https://random-site.xyz
# ⚠ WARN — HTTP request to unrecognized domain

agent-shield http-check -m POST -b '{"key":"AKIAIOSFODNN7EXAMPLE"}' https://api.example.com
# ✗ DENY — Request body contains potential secrets

Start the HTTP proxy

agent-shield http-proxy --port 8080

Then route agent traffic through it:

HTTP_PROXY=http://localhost:8080 HTTPS_PROXY=http://localhost:8080 your-agent

Default HTTP rules block:

  • Exfiltration domains (pastebin, ngrok, webhook.site, requestbin, etc.)
  • File uploads (multipart/form-data) to external services
  • Secret leaks in request bodies (AWS keys, GitHub PATs, private keys, Stripe/OpenAI keys)

Allows:

  • Dev domains (GitHub, npm, PyPI, localhost)
  • AI/cloud APIs (OpenAI, Anthropic, Google, AWS, Azure)

Web Dashboard

agent-shield dashboard
# ✓ Dashboard running at http://localhost:4040

Provides:

  • Live Feed — Real-time stream of every tool call with policy decisions
  • Analytics — Total calls, allow/deny/warn breakdown, top tools, latency
  • Anomaly Alerts — Volume spikes, new tool access, off-hours activity, high deny rates
  • Policy Reference — Quick view of your current rules

The dashboard reads from SQLite, so it works even when the proxy isn't running. (Requires optional better-sqlite3 — see Optional Dependencies).


Audit Log

Every intercepted call is logged as structured JSON:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "server_name": "github",
  "agent_id": "claude-code",
  "method": "tools/call",
  "tool_name": "create_issue",
  "arguments": { "project": "PROD", "title": "Fix bug" },
  "result_preview": "Created issue PROD-123",
  "policy_decision": "allow",
  "policy_rule": "allow-reads",
  "latency_ms": 142,
  "error": null
}
  • Secrets are automatically redacted before logging (AWS keys, GitHub tokens, Slack tokens, API keys, passwords, emails)
  • Log file is structured JSON (one entry per line) — pipe to jq, Datadog, or any log aggregator
  • Policy file changes are hot-reloaded — no restart needed

Query logs with CLI

agent-shield logs                             # Show recent entries
agent-shield logs --filter write_file         # Filter by tool name
agent-shield logs --action deny               # Show only blocked calls
agent-shield logs --server github --json      # JSON output for piping

All CLI Commands

Command Description
agent-shield start --server <name> Start the MCP proxy (called by agent config)
agent-shield logs View audit log entries
agent-shield policy validate Validate your policy file
agent-shield dashboard Launch web dashboard
agent-shield exec <command> Run a shell command through policy
agent-shield exec --dry-run <command> Check if a command would be allowed
agent-shield hook show Show Claude Code hook config
agent-shield hook test <command> Test hook policy for a command
agent-shield http-proxy --port <port> Start HTTP forward proxy
agent-shield http-check <url> Check a URL against HTTP policy

Policy Rule Reference

Rules are evaluated top-to-bottom. First match wins (like iptables/nginx).

Field Type Description
name string Human-readable rule name
action allow | deny | warn What to do when matched
servers string[] Match specific servers (omit = all)
tools string[] Match specific tools (omit = all)
args_match object Regex matching on tool arguments
rate_limit { max_calls, window_seconds } Rate limiting (only with allow)
time_window { start, end, timezone } Time-of-day restrictions (HH:MM)
message string Shown on deny, logged on warn

Actions

  • allow — permit the call and log it
  • deny — block the call, return an error to the agent, and log it
  • warn — permit the call but flag it for review in logs/dashboard

Features

  • Policy enforcement — Allow/deny/warn rules with first-match-wins evaluation
  • Rate limiting — Per-tool call limits with configurable time windows
  • Audit logging — Structured JSON logs, queryable via CLI
  • SQLite storage — Queryable audit data for dashboard and analytics (optional)
  • Secret redaction — Auto-redacts API keys, tokens, passwords, emails before logging
  • Hot-reload — Edit your policy file and changes apply instantly, no restart needed
  • Web dashboard — Real-time feed, analytics, top tools, anomaly alerts
  • Anomaly detection — Volume spikes, new tools, off-hours activity, high deny rates
  • CLI command interception — Intercept shell commands agents run, not just MCP
  • HTTP request interception — Forward proxy with domain blocking and secret leak scanning
  • Claude Code hooks — Drop-in PreToolUse hook for Bash tool interception
  • SSE transport — Proxy remote MCP servers over HTTP (not just local stdio)
  • Works with any agent — Claude Code, Cursor, Windsurf, or custom agents

Optional Dependencies

AgentShield works out of the box with zero native dependencies. Some features require optional packages:

Feature Package Install
Dashboard + SQLite storage better-sqlite3 npm install better-sqlite3

If better-sqlite3 is not installed, AgentShield still works — it just uses JSON file logging instead of SQLite, and the dashboard won't be available.


Contributing

git clone https://github.com/inprod/agent-shield.git
cd agent-shield
npm install
npm test        # 146 tests
npm run build   # compile TypeScript

License

MIT

About

Security Policies towards AI agent

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages