Skip to main content

gh-aw-firewall

Network egress control for AI agents with domain whitelisting, Squid proxy, iptables enforcement, and secure credential management

Source facts

Repository
Hack23/riksdagsmonitor
Last source activity
April 26, 2026 at 17:53
Detected SKILL.md language
English
Stars
12
Forks
4

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
gh-aw-firewall
description
Network egress control for AI agents with domain whitelisting, Squid proxy, iptables enforcement, and secure credential management
license
Apache-2.0
version
2.0.1
last_updated
2026-04-13T00:00:00.000Z
tags
["github-agentic-workflows","network-security","firewall","squid","domain-whitelisting","egress-control"]
# 🔥 GitHub Agentic Workflows - Firewall Skill ## 🔴 AI FIRST Quality Principle > **Apply the AI FIRST principle: never accept first-pass quality. Minimum 2 iterations. Read all output, improve every section. No shortcuts.** ## 📋 Purpose Master the **Agentic Workflow Firewall (AWF)** - a network firewall for agentic workflows providing L7 (HTTP/HTTPS) egress control using Squid proxy and Docker containers. This skill provides comprehensive expertise in restricting network access to a whitelist of approved domains for AI agents and their MCP servers. ## 🎯 Core Concepts ### What is AWF? **AWF (Agentic Workflow Firewall)** is a network security layer that restricts AI agent network access to explicitly approved domains, preventing data exfiltration and unauthorized external communication. **Key Features:** - 🌐 **L7 Domain Whitelisting**: HTTP/HTTPS traffic control at application layer - 🔒 **Host-Level Enforcement**: iptables DOCKER-USER chain for all containers - 📦 **Chroot Mode**: Host binaries with network isolation - 🔑 **API Proxy Sidecar**: Secure LLM credential management - ✅ **Transparent**: Works with existing containers ### Security Model ``` ┌────────────────────────────────────────────────┐ │ AI Agent Container │ │ ┌──────────────────────────────────────┐ │ │ │ Application Code │ │ │ │ (Read-only filesystem) │ │ │ └───────────────┬──────────────────────┘ │ │ │ Network Request │ │ ▼ │ │ ┌──────────────────────────────────────┐ │ │ │ iptables DOCKER-USER Chain │ │ │ │ (Force all traffic through Squid) │ │ │ └───────────────┬──────────────────────┘ │ └──────────────────┼──────────────────────────────┘ │ ▼ ┌───────────────────────────────┐ │ Squid Proxy │ │ ┌─────────────────────────┐ │ │ │ Domain Whitelist │ │ │ │ - github.com ✅ │ │ │ │ - api.github.com ✅ │ │ │ │ - evil.com ❌ │ │ │ └─────────────────────────┘ │ │ │ │ ┌─────────────────────────┐ │ │ │ SSL Bump (HTTPS) │ │ │ │ (Content Inspection) │ │ │ └─────────────────────────┘ │ └────────────┬──────────────────┘ │ ▼ External Network (Allowed domains only) ``` ## 🏗️ Architecture ### Three Operating Modes #### 1. Standard Mode (Default) ```bash awf --allow-domains github.com,api.github.com -- docker run myapp ``` **How it works:** - Launches Squid proxy with domain whitelist - Creates iptables rules in DOCKER-USER chain - Runs command in Docker container - All HTTP/HTTPS traffic forced through Squid - Unauthorized domains blocked #### 2. Chroot Mode ```bash awf --chroot --allow-domains github.com -- python3 script.py ``` **How it works:** - Uses host binaries (Python, Node.js, Go) - Transparent network isolation - No Docker container overhead - Squid proxy still enforces whitelist **Use Cases:** - Faster startup (no container pull) - Access to host tools - Still network-isolated #### 3. API Proxy Sidecar ```bash awf --api-proxy --allow-domains api.openai.com,api.anthropic.com -- node agent.js ``` **How it works:** - Node.js proxy for LLM API calls - Credentials injected securely - Tokens never exposed to AI agent - All calls routed through Squid ## 🔧 Configuration ### CLI Usage **Basic Command Structure:** ```bash awf [firewall-options] -- [command-to-run] ``` The `--` separator divides firewall configuration from the command to execute. ### Domain Allowlisting **Single Domain:** ```bash awf --allow-domains github.com -- curl https://api.github.com ``` **Multiple Domains:** ```bash awf --allow-domains github.com,api.openai.com,anthropic.com -- python agent.py ``` **Wildcard Subdomains:** ```bash awf --allow-domains '*.github.com' -- npm install ``` **Domain File:** ```bash # domains.txt github.com api.github.com *.githubusercontent.com awf --allow-domains-file domains.txt -- git clone https://github.com/repo ``` ### Environment Variables **Passing Variables to Container:** ```bash awf --env API_KEY --env DEBUG -- node app.js ``` **With Values:** ```bash awf --env API_KEY=secret123 -- python script.py ``` **From File:** ```bash # .env file API_KEY=secret123 DEBUG=true awf --env-file .env -- npm start ``` ### Installation **Quick Install:** ```bash curl -sSL https://raw.githubusercontent.com/github/gh-aw-firewall/main/install.sh | sudo bash ``` **Manual Install:** ```bash npm install -g gh-aw-firewall ``` **Verify:** ```bash awf --version awf --help ``` ## 🔐 API Proxy Sidecar ### Secure Credential Management The API proxy sidecar provides secure credential management for LLM APIs (OpenAI, Anthropic) without exposing tokens to AI agents. **Architecture:** ``` ┌──────────────────────────────────────┐ │ AI Agent Container │ │ ┌────────────────────────────┐ │ │ │ Code makes API call │ │ │ │ http://localhost:8080/v1 │ │ │ │ (No API key in code) │ │ │ └──────────────┬─────────────┘ │ └─────────────────┼────────────────────┘ │ ▼ ┌─────────────────────────────┐ │ API Proxy Sidecar │ │ ┌──────────────────────┐ │ │ │ Inject Credentials │ │ │ │ Authorization: sk-xx │ │ │ └──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────┐ │ │ │ Route via Squid │ │ │ └──────────────────────┘ │ └───────────┬─────────────────┘ │ ▼ ┌─────────────┐ │ Squid Proxy │ │ (Whitelist) │ └──────┬──────┘ │ ▼ External API (api.openai.com) ``` **Configuration:** ```bash # Export credentials (not visible to agent) export OPENAI_API_KEY=sk-xxx export ANTHROPIC_API_KEY=sk-ant-xxx # Start with API proxy awf --api-proxy \ --allow-domains api.openai.com,api.anthropic.com \ -- node agent.js ``` **Agent Code:** ```javascript // Agent makes calls without credentials fetch('http://localhost:8080/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'gpt-4', messages: [...] }) }); // API proxy automatically injects: // Authorization: Bearer sk-xxx ``` **Benefits:** - ✅ Credentials never in agent code - ✅ Tokens isolated in proxy - ✅ All traffic still goes through Squid - ✅ Domain whitelist enforced - ✅ Logging and monitoring ### Implementation Example **Go Proxy Server:** ```go package main import ( "net/http" "net/http/httputil" "net/url" "os" ) func main() { // Read credentials from environment openaiKey := os.Getenv("OPENAI_API_KEY") anthropicKey := os.Getenv("ANTHROPIC_API_KEY") // Squid proxy URL squidURL, _ := url.Parse("http://squid:3128") // Create reverse proxy proxy := httputil.NewSingleHostReverseProxy(squidURL) // Modify request to inject credentials director := proxy.Director proxy.Director = func(req *http.Request) { director(req) // Inject appropriate credential if req.Host == "api.openai.com" { req.Header.Set("Authorization", "Bearer "+openaiKey) } else if req.Host == "api.anthropic.com" { req.Header.Set("x-api-key", anthropicKey) } // Route through Squid req.URL.Host = req.Host req.URL.Scheme = "https" } http.ListenAndServe(":8080", proxy) } ``` ## 🌐 SSL Bump (HTTPS Inspection) ### Content Inspection SSL Bump allows Squid to inspect HTTPS traffic for URL path filtering and content validation. **Configuration:** ```squid # Enable SSL Bump http_port 3128 ssl-bump \ cert=/etc/squid/certs/squid-ca-cert.pem \ key=/etc/squid/certs/squid-ca-key.pem # SSL Bump rules acl step1 at_step SslBump1 ssl_bump peek step1 ssl_bump bump all # URL path filtering acl allowed_paths url_regex ^https://api\.github\.com/repos/ http_access allow allowed_paths http_access deny all ``` **Use Cases:** - ✅ Block specific URL paths - ✅ Content validation - ✅ Deep packet inspection - ✅ Logging HTTPS requests **Security Considerations:** - ⚠️ Requires CA certificate in agent - ⚠️ Man-in-the-middle by design - ✅ Transparent to agent code - ✅ Logs include HTTPS details ## 🔄 GitHub Actions Integration ### Basic Workflow ```yaml name: Agentic Workflow with Firewall on: pull_request jobs: agent: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install AWF run: | curl -sSL https://raw.githubusercontent.com/github/gh-aw-firewall/main/install.sh | sudo bash - name: Run Agent with Firewall run: | awf --allow-domains github.com,api.github.com \ -- node agent.js env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` ### MCP Server Configuration ```yaml - name: Run MCP Server with Firewall run: | awf --allow-domains github.com,api.githubcopilot.com \ --env GITHUB_TOKEN \ -- docker run -i \ -e GITHUB_TOKEN \ ghcr.io/github/github-mcp-server:latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ``` ### Multi-Stage Pipeline ```yaml jobs: build: runs-on: ubuntu-latest steps: - name: Build with NPM Registry run: | awf --allow-domains registry.npmjs.org \ -- npm install - name: Test with External APIs run: | awf --allow-domains api.github.com,api.openai.com \ --api-proxy \ -- npm test env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - name: Deploy (No Network) run: | awf --allow-domains '' \ -- npm run build ``` ## 📊 Logging & Monitoring ### Log Files **Squid Access Log:** ```bash # Location /var/log/squid/access.log # Format timestamp ip method url status bytes # View recent tail -f /var/log/squid/access.log # Filter blocked requests grep "TCP_DENIED" /var/log/squid/access.log ``` **Squid Cache Log:** ```bash # Location /var/log/squid/cache.log # Contains - Squid startup/shutdown - Configuration errors - Domain whitelist violations # Monitor tail -f /var/log/squid/cache.log ``` ### Quick Reference **View All Traffic:** ```bash awf --log-level debug --allow-domains github.com -- curl https://api.github.com ``` **Filter by Domain:** ```bash grep "github.com" /var/log/squid/access.log ``` **Count Requests:** ```bash awk '{print $7}' /var/log/squid/access.log | sort | uniq -c | sort -rn ``` **Blocked Requests:** ```bash grep "TCP_DENIED" /var/log/squid/access.log | awk '{print $7}' | sort | uniq ``` ### Monitoring Metrics **Prometheus Exporter:** ```yaml # docker-compose.yml services: squid-exporter: image: boynux/squid-exporter ports: - "9301:9301" environment: - SQUID_HOSTNAME=squid - SQUID_PORT=3128 ``` **Grafana Dashboard:** - Total requests - Allowed vs denied - Top domains - Response times - Cache hit rate ## 🔧 Troubleshooting ### Common Issues #### 1. Connection Refused **Symptom:** ``` Error: connect ECONNREFUSED 127.0.0.1:3128 ``` **Diagnosis:** ```bash # Check Squid is running ps aux | grep squid # Check Squid port netstat -tlnp | grep 3128 # Check Squid logs tail /var/log/squid/cache.log ``` **Solutions:** - Ensure Squid container is running - Verify iptables rules are applied - Check Squid configuration syntax #### 2. Domain Not Whitelisted **Symptom:** ``` HTTP 403 Forbidden TCP_DENIED/403 ``` **Diagnosis:** ```bash # Check domain in whitelist grep "example.com" /etc/squid/allowed-domains.txt # View denied requests grep "TCP_DENIED" /var/log/squid/access.log | tail -20 ``` **Solutions:** - Add domain to whitelist - Use subdomain wildcard sparingly: `*.example.com` (for known trusted organizations only) - Check for typos in domain name > ⚠️ **NEVER use TLD-level wildcards** like `*.com`, `*.org`, `*.se`, `*.io` — these effectively disable the firewall by allowing all traffic to those TLDs. Always use explicit domain names (e.g., `api.example.com`, `data.example.se`) or scoped subdomain wildcards for trusted organizations only. #### 3. SSL Certificate Issues **Symptom:** ``` Error: certificate verify failed ``` **Diagnosis:** ```bash # Check CA certificate ls -la /etc/squid/certs/
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub