Skip to content

MixTapeSoftware/agent_proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentProxy: AI Safety Proxy

A mitmproxy-based security layer that protects against data exfiltration and malicious traffic when using AI assistants and agents.

Credits

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

Overview

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.

Table of Contents

How It Works

AI Assistant → AgentProxy → Internet
                    ↓
              Blocklists + Rules
                    ↓
              mitmproxy logs

The proxy inspects every HTTP/HTTPS request and:

  1. Checks if domain is whitelisted (bypasses all other checks)
  2. Checks domain against blocklists (malware, phishing)
  3. Checks URL against custom regex patterns
  4. Blocks requests with bodies larger than threshold (default 10KB)
  5. Blocks configured write methods (default: POST, PUT, PATCH, DELETE)
  6. Logs all decisions via mitmproxy

Installation

Prerequisites

Quick Setup

  1. Clone this repository:
git clone <your-repo-url>
cd agent-proxy
  1. Run the setup script:
./setup.sh

This 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
  1. Update blocklists:
uv run update_blocklists.py

Manual Setup

If 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.txt

This 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 --help

Cron Jobs

For automated blocklist updates:

0 2 * * * cd /path/to/agent-proxy && uv run update_blocklists.py

Logs are written to ~/.local/state/agent_proxy/logs/blocklist_update.log by default.

Installation Troubleshooting

Command not found: uv

Install uv:

curl -LsSf https://astral.sh/uv/install.sh | sh

Or 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/releases

Permission denied

If you get permission errors, ensure the directory is writable:

ls -ld /path/to/agent-proxy
chmod 755 /path/to/agent-proxy

Python version mismatch

If you need a specific Python version:

uv venv --python 3.11

Or create a .python-version file:

echo "3.11" > .python-version
uv venv

Uninstalling

To remove the virtual environment and all application data:

./uninstall.sh

This removes:

  • .venv/ (virtual environment)
  • ~/.local/share/agent_proxy/ (blocklists)
  • ~/.local/state/agent_proxy/ (logs)

Keeping Dependencies Updated

To check for updates:

uv pip list --outdated

To update all packages:

uv pip install --upgrade -r requirements.txt

To generate a lock file (optional, for reproducible installs):

uv pip compile requirements.txt -o requirements.lock
uv pip install -r requirements.lock

Usage

Running the Proxy

Background 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.log

Foreground 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 decisions

Running as a Service (systemd)

For 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 -f

Logs 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.

Configuring Claude Code

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.log

Important 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

SSL/TLS Certificate Setup

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 mitmdump

Install 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.pem

Verify the setup:

# Should complete without SSL errors
curl https://example.com

Note: 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.

Configuration

AgentProxy is configured via environment variables with sensible defaults.

Environment Variables

# 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"

Example Configurations

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 8080

Strict 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 8080

Whitelist trusted domains:

export AGENT_PROXY_ALLOWED_DOMAINS="api.openai.com,api.anthropic.com"
mitmdump -s main.py --listen-port 8080

Blocklists

Blocklists 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

Custom Domain Blocklists

Add your own domain blocklists:

echo "evil.example.com" >> blocklists/custom.domains
echo "malware.test" >> blocklists/custom.domains

Custom URL Patterns

Block 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
EOF

Monitoring

Logging

AgentProxy 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).

View Logs

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.log

Console 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=warn

Interactive 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 close

Log Format

2026-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

Security Considerations

What This Protects Against

  • 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.

What This Does NOT Protect Against

  • 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

Defense in Depth

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

Troubleshooting

Proxy Not Working

# Verify proxy is running
curl -x http://localhost:8080 http://example.com

# Check if port is in use
lsof -i :8080

Certificate Errors

# 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 steps

Too Many False Positives

If legitimate traffic is being blocked:

  1. Check logs to identify the blocking rule
  2. 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
  3. Remove problematic patterns from blocklists/patterns.txt
  4. Remove problematic domains from blocklists

Development

Testing

# 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.com

Extending

To 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}")
    # return

Example - 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 ...

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Submit a pull request

Resources

Acknowledgments

  • URLhaus by abuse.ch for malware domain feeds
  • Mitchell Krogza for phishing domain database
  • mitmdump project for the excellent proxy framework

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published