A mitmproxy-based security layer that protects against data exfiltration and malicious traffic when using AI assistants and agents.
This project is built on top of:
- mitmproxy - An excellent open-source interactive HTTPS proxy (MIT License)
- URLhaus by abuse.ch - Malware domain blocklists
- Phishing Database by Mitchell Krogza - Phishing domain blocklists
AgentProxy acts as a transparent HTTP(S) proxy between your AI assistant and the internet, enforcing security policies to prevent:
- Data exfiltration: Blocks large outbound requests and write operations
- Malware/phishing: Blocks known malicious domains from curated blocklists
- Suspicious patterns: Blocks URLs matching custom regex patterns
- Write operations: Prevents POST/PUT/PATCH/DELETE requests (configurable)
- Domain whitelisting: Allow trusted domains to bypass all checks
All traffic is logged through mitmproxy for auditing and security analysis.
- How It Works
- Installation
- Usage
- Configuration
- Monitoring
- Security Considerations
- Troubleshooting
- Development
- Contributing
- Resources
- Acknowledgments
AI Assistant → AgentProxy → Internet
↓
Blocklists + Rules
↓
mitmproxy logs
The proxy inspects every HTTP/HTTPS request and:
- Checks if domain is whitelisted (bypasses all other checks)
- Checks domain against blocklists (malware, phishing)
- Checks URL against custom regex patterns
- Blocks requests with bodies larger than threshold (default 10KB)
- Blocks configured write methods (default: POST, PUT, PATCH, DELETE)
- Logs all decisions via mitmproxy
- Python 3.9+
uvpackage manager (install uv)
- Clone this repository:
git clone <your-repo-url>
cd agent-proxy- Run the setup script:
./setup.shThis creates a virtual environment, installs dependencies, and verifies the installation.
On Linux, add --with-systemd to automatically install and start the proxy as a systemd service:
./setup.sh --with-systemd- Update blocklists:
uv run update_blocklists.pyIf you prefer manual control or the setup script fails:
1. Create Virtual Environment and Install Dependencies
cd /path/to/agent-proxy
uv venv
uv pip install -r requirements.txtThis creates a .venv directory and installs:
- mitmdump (mitmproxy proxy server non-interactive version)
- beautifulsoup4 (HTML parsing)
- nh3 (text sanitization)
- lxml (fast HTML parser backend)
2. Verify Installation
uv run update_blocklists.py --helpFor automated blocklist updates:
0 2 * * * cd /path/to/agent-proxy && uv run update_blocklists.pyLogs are written to ~/.local/state/agent_proxy/logs/blocklist_update.log by default.
Command not found: uv
Install uv:
curl -LsSf https://astral.sh/uv/install.sh | shOr use your package manager:
# macOS with Homebrew
brew install uv
# Ubuntu/Debian (via pip)
pip install uv
# Or download from https://github.com/astral-sh/uv/releasesPermission denied
If you get permission errors, ensure the directory is writable:
ls -ld /path/to/agent-proxy
chmod 755 /path/to/agent-proxyPython version mismatch
If you need a specific Python version:
uv venv --python 3.11Or create a .python-version file:
echo "3.11" > .python-version
uv venvTo remove the virtual environment and all application data:
./uninstall.shThis removes:
.venv/(virtual environment)~/.local/share/agent_proxy/(blocklists)~/.local/state/agent_proxy/(logs)
To check for updates:
uv pip list --outdatedTo update all packages:
uv pip install --upgrade -r requirements.txtTo generate a lock file (optional, for reproducible installs):
uv pip compile requirements.txt -o requirements.lock
uv pip install -r requirements.lockBackground mode (typical production use):
# Run in background with nohup
nohup mitmdump -s main.py --set block_global=false --listen-port 8080 &
# Or with screen/tmux
screen -dmS agent_proxy mitmdump -s main.py --set block_global=false --listen-port 8080
# Check logs
tail -f ~/.local/state/agent_proxy/logs/access.logForeground mode (testing/debugging):
# Console mode - see logs in terminal
mitmdump -s main.py --set block_global=false --listen-port 8080
# Interactive mode - use TUI to inspect traffic
mitmdump -s main.py --set block_global=false --listen-port 8080
# Press 'e' to view event log with all blocking decisionsFor production deployments, run AgentProxy as a systemd service:
# Create service file
sudo tee /etc/systemd/system/agent-proxy.service << 'EOF'
[Unit]
Description=AgentProxy - AI Safety Proxy
After=network.target
[Service]
Type=simple
User=your-username
ExecStart=/[YOUR-HOME-DIR/.local/bin/mitmdump -s /path/to/main.py --set block_global=false --listen-port 8080
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable agent-proxy
sudo systemctl start agent-proxy
# Check status
sudo systemctl status agent-proxy
# View logs
sudo journalctl -u agent-proxy -fLogs and blocklists use XDG paths in the service user's home directory by default. Override with AGENT_PROXY_BLOCKLIST_DIR and AGENT_PROXY_LOG_FILE environment variables if needed.
Before configuring the proxy, make sure you have Claude Code set up with sandboxing enabled. See the Claude Code sandboxing guide to get started.
Configure Claude Code to route network requests through the proxy by editing ~/.claude/settings.json:
{
"sandbox": {
"network": {
"proxy": "http://localhost:8080"
}
}
}This configures the proxy for all network requests made by Claude Code's sandboxed bash commands, ensuring that tools like curl, wget, and package managers route through the proxy.
Verify it's working:
Start Claude Code and have it make a web request:
claude
# Then in Claude: "run curl https://example.com"Check the proxy logs to see the request:
tail -f ~/.local/state/agent_proxy/logs/access.logImportant limitations:
- This proxy only affects network requests made from your local machine through Claude Code's sandbox
- Tools that execute on remote servers (such as Claude's WebFetch tool, which runs on Anthropic's servers) will not route through this proxy
- For more sandbox configuration options, see the Claude Code sandbox settings documentation
For HTTPS traffic inspection, mitmproxy acts as a man-in-the-middle by presenting its own certificates. You need to install mitmdump's CA certificate to avoid SSL verification errors.
Generate the certificate (if not already present):
# Start mitmdump once to generate certificates in ~/.mitmproxy/
mitmdump -s main.py &
sleep 2
killall mitmdumpInstall the certificate system-wide:
Linux:
sudo cp ~/.mitmdump/mitmdump-ca-cert.pem /usr/local/share/ca-certificates/mitmdump.crt
sudo update-ca-certificates
# Should show "1 added, 0 removed"macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/.mitmdump/mitmdump-ca-cert.pemVerify the setup:
# Should complete without SSL errors
curl https://example.comNote: If you see SSL certificate problem: unable to get local issuer certificate, the CA cert isn't trusted yet. Re-run the installation steps above.
AgentProxy is configured via environment variables with sensible defaults.
# Blocklist directory (default: ~/.local/share/agent_proxy/blocklists/)
export AGENT_PROXY_BLOCKLIST_DIR="/path/to/blocklists"
# Log file location (default: ~/.local/state/agent_proxy/logs/access.log)
export AGENT_PROXY_LOG_FILE="/path/to/access.log"
# Maximum request body size in bytes (default: 10240 = 10KB)
export AGENT_PROXY_MAX_BODY_SIZE=20480
# HTTP methods to block, comma-separated (default: POST,PUT,PATCH,DELETE)
export AGENT_PROXY_BLOCK_METHODS="PUT,DELETE"
# Domains to whitelist, comma-separated (default: none)
export AGENT_PROXY_ALLOWED_DOMAINS="api.anthropic.com,github.com"Permissive mode - Only block known bad domains:
export AGENT_PROXY_BLOCK_METHODS="" # Don't block any HTTP methods
export AGENT_PROXY_MAX_BODY_SIZE=1048576 # Allow 1MB requests
mitmdump -s main.py --listen-port 8080Strict mode - Block most activity:
export AGENT_PROXY_BLOCK_METHODS="POST,PUT,PATCH,DELETE,OPTIONS"
export AGENT_PROXY_MAX_BODY_SIZE=1024 # Only 1KB requests
mitmdump -s main.py --listen-port 8080Whitelist trusted domains:
export AGENT_PROXY_ALLOWED_DOMAINS="api.openai.com,api.anthropic.com"
mitmdump -s main.py --listen-port 8080Blocklists are stored in the configured directory (default: ~/.local/share/agent_proxy/blocklists/):
*.domains- Domain blocklists (one domain per line)patterns.txt- Regex patterns to block (one pattern per line)
Default blocklists include:
- URLhaus: Known malware distribution domains
- Phishing Database: Active phishing domains
Add your own domain blocklists:
echo "evil.example.com" >> blocklists/custom.domains
echo "malware.test" >> blocklists/custom.domainsBlock URLs matching regex patterns:
cat > blocklists/patterns.txt << 'EOF'
# Block pastebin-like services
pastebin\.com
paste\..*
# Block file sharing
dropbox\.com/s/
drive\.google\.com/.*share
EOFAgentProxy logs to both the console (mitmdump's output) and a file. This dual approach ensures:
- Real-time monitoring when running interactively
- Persistent logs when running as a background service
The log file location is configurable via AGENT_PROXY_LOG_FILE (default: ~/.local/state/agent_proxy/logs/access.log).
File logs (recommended for background operation):
# Follow live traffic
tail -f ~/.local/state/agent_proxy/logs/access.log
# View blocked requests
grep BLOCKED ~/.local/state/agent_proxy/logs/access.log
# View allowed requests
grep OK ~/.local/state/agent_proxy/logs/access.log
# View recent activity
tail -100 ~/.local/state/agent_proxy/logs/access.logConsole mode (mitmdump) - for interactive use:
# All logs appear in terminal AND the log file
mitmdump -s main.py --listen-port 8080
# Show only warnings and errors in console
mitmdump -s main.py --listen-port 8080 --set termlog_verbosity=warnInteractive mode (mitmdump) - for debugging:
mitmdump -s main.py --listen-port 8080
# Press 'e' to view the event log
# Use arrow keys to navigate, 'q' to close2026-01-26 10:30:15 [INFO] OK GET https://api.anthropic.com/v1/messages (512b)
2026-01-26 10:30:20 [WARNING] BLOCKED [domain] GET https://malware.example.com/
2026-01-26 10:30:25 [WARNING] BLOCKED [POST] POST https://api.example.com/upload
2026-01-26 10:30:30 [WARNING] BLOCKED [body size 15360] POST https://api.example.com/
2026-01-26 10:30:35 [WARNING] BLOCKED [pattern] GET https://pastebin.com/suspicious
- HTTP requests to domains in your blocklists - Prevents the AI from fetching content from known malware/phishing domains you've configured
- HTTP POST/PUT/PATCH/DELETE requests - Blocks the AI from sending data via write methods (as configured)
- HTTP requests with large request bodies - Prevents sending large amounts of data in a single request (configurable threshold, default 10KB)
- HTTP requests matching your custom regex patterns - Blocks URLs that match patterns you've defined
This provides a baseline network-level control layer for HTTP traffic. Effectiveness depends on blocklist quality and configuration.
- Remote tool execution - Tools that execute on remote servers (e.g., Claude's WebFetch, which runs on Anthropic's servers) bypass this proxy entirely
- DNS exfiltration (use DNS filtering separately)
- Data exfiltration via GET request URLs under the size limit
- Domains not in your blocklists - only blocks what you've explicitly configured
- Non-HTTP protocols (e.g., raw TCP, UDP)
- Sophisticated techniques like data chunking across multiple small requests
- Application-layer exploits in the AI tool itself
- Social engineering or prompt injection that doesn't involve network requests
AgentProxy is one layer of security. Combine with:
- Filesystem sandboxing (AppArmor, SELinux)
- Network segmentation
- Principle of least privilege
- Regular security audits of AI tool permissions
- Code review of custom tools and extensions
# Verify proxy is running
curl -x http://localhost:8080 http://example.com
# Check if port is in use
lsof -i :8080# Verify certificate is installed
openssl s_client -connect example.com:443 -proxy localhost:8080
# Reinstall certificate if needed
rm -rf ~/.mitmdump
# Then re-run the SSL/TLS setup stepsIf legitimate traffic is being blocked:
- Check logs to identify the blocking rule
- Use environment variables to adjust limits:
- Increase
AGENT_PROXY_MAX_BODY_SIZE - Reduce blocked methods with
AGENT_PROXY_BLOCK_METHODS - Whitelist domains with
AGENT_PROXY_ALLOWED_DOMAINS
- Increase
- Remove problematic patterns from
blocklists/patterns.txt - Remove problematic domains from blocklists
# Test domain blocking
curl -x http://localhost:8080 http://malware.example.com
# Test size blocking
dd if=/dev/zero bs=1024 count=20 | curl -x http://localhost:8080 -X POST -d @- http://httpbin.org/post
# Test method blocking
curl -x http://localhost:8080 -X POST http://example.comTo add new blocking rules, edit the request() method in main.py:
def request(self, flow: mitmdump.http.HTTPFlow) -> None:
# Add your custom rules here
if custom_condition:
self._block_request(flow, 'reason', method, url)
return
# Or manually:
# flow.kill()
# ctx.log.warning(f"BLOCKED [reason] {method} {url}")
# returnExample - block requests to specific paths:
def request(self, flow: mitmdump.http.HTTPFlow) -> None:
# ... existing checks ...
# Block admin paths
if '/admin' in flow.request.path:
self._block_request(flow, 'admin path', flow.request.method, url)
return
# ... rest of checks ...Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
- URLhaus by abuse.ch for malware domain feeds
- Mitchell Krogza for phishing domain database
- mitmdump project for the excellent proxy framework