π₯ GitHub Agentic Workflows - Firewall Skill
π 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
- Standard Mode (Default)
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
- Chroot Mode
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
- API Proxy Sidecar
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:
awf [firewall-options] -- [command-to-run]
The -- separator divides firewall configuration from the command to execute.
Domain Allowlisting
Single Domain:
awf --allow-domains github.com -- curl https://api.github.com
Multiple Domains:
awf --allow-domains github.com,api.openai.com,anthropic.com -- python agent.py
Wildcard Subdomains:
awf --allow-domains '*.github.com' -- npm install
Domain File:
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:
awf --env API_KEY --env DEBUG -- node app.js
With Values:
awf --env API_KEY=secret123 -- python script.py
From File:
.env file
API_KEY=secret123 DEBUG=true
awf --env-file .env -- npm start
Installation
Quick Install:
curl -sSL https://raw.githubusercontent.com/github/gh-aw-firewall/main/install.sh | sudo bash
Manual Install:
npm install -g gh-aw-firewall
Verify:
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:
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:
// 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:
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:
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
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
- 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
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:
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:
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:
awf --log-level debug --allow-domains github.com -- curl https://api.github.com
Filter by Domain:
grep "github.com" /var/log/squid/access.log
Count Requests:
awk '{print $7}' /var/log/squid/access.log | sort | uniq -c | sort -rn
Blocked Requests:
grep "TCP_DENIED" /var/log/squid/access.log | awk '{print $7}' | sort | uniq
Monitoring Metrics
Prometheus Exporter:
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
- Connection Refused
Symptom:
Error: connect ECONNREFUSED 127.0.0.1:3128
Diagnosis:
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
- Domain Not Whitelisted
Symptom:
HTTP 403 Forbidden TCP_DENIED/403
Diagnosis:
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 wildcard: *.example.com
-
Check for typos in domain name
- SSL Certificate Issues
Symptom:
Error: certificate verify failed
Diagnosis:
Check CA certificate
ls -la /etc/squid/certs/
Test SSL connection
openssl s_client -connect api.github.com:443 -proxy localhost:3128
Solutions:
-
Install Squid CA certificate in container
-
Disable SSL Bump if not needed
-
Use --insecure flag for testing (not production)
- Performance Issues
Symptom:
-
Slow response times
-
High latency
Diagnosis:
Check Squid CPU/memory
docker stats squid
Monitor request timing
tail -f /var/log/squid/access.log | grep -o "TCP_[A-Z_]*"
Solutions:
-
Increase Squid cache size
-
Add more Squid workers
-
Use connection pooling
-
Enable HTTP/2
- Docker Networking
Symptom:
Error: network unreachable
Diagnosis:
Check Docker network
docker network ls docker network inspect awf-network
Check iptables
sudo iptables -L DOCKER-USER -n -v
Solutions:
-
Verify Docker network exists
-
Check iptables rules are applied
-
Restart Docker daemon
βοΈ Advanced Configuration
Custom Squid Configuration
squid.conf:
Basic ACLs
acl localnet src 172.16.0.0/12 acl SSL_ports port 443 acl Safe_ports port 80 acl CONNECT method CONNECT
Allowed domains from file
acl allowed_domains dstdomain "/etc/squid/allowed-domains.txt"
Deny CONNECT to other than SSL ports
http_access deny CONNECT !SSL_ports
Allow only safe ports
http_access deny !Safe_ports
Allow localhost
http_access allow localnet
Allow only whitelisted domains
http_access allow allowed_domains
Deny everything else
http_access deny all
Logging
access_log /var/log/squid/access.log squid cache_log /var/log/squid/cache.log
Performance
cache_mem 256 MB maximum_object_size 50 MB cache_dir ufs /var/spool/squid 1000 16 256
DNS
dns_nameservers 8.8.8.8 8.8.4.4
Docker Compose Setup
version: '3.8'
services: squid: image: ubuntu/squid:latest container_name: awf-squid ports: - "3128:3128" volumes: - ./squid.conf:/etc/squid/squid.conf:ro - ./allowed-domains.txt:/etc/squid/allowed-domains.txt:ro - squid-cache:/var/spool/squid - squid-logs:/var/log/squid networks: - awf-network restart: unless-stopped
agent: image: myagent:latest depends_on: - squid environment: - HTTP_PROXY=http://squid:3128 - HTTPS_PROXY=http://squid:3128 networks: - awf-network
networks: awf-network: driver: bridge
volumes: squid-cache: squid-logs:
iptables Rules
Automatic (via AWF):
awf --allow-domains github.com -- docker run myapp
iptables rules applied automatically
Manual:
Force all container traffic to Squid
sudo iptables -I DOCKER-USER -p tcp --dport 80 -j REDIRECT --to-port 3128 sudo iptables -I DOCKER-USER -p tcp --dport 443 -j REDIRECT --to-port 3128
Verify rules
sudo iptables -L DOCKER-USER -n -v
π― Best Practices
- Principle of Least Privilege
β DON'T: Allow all subdomains
awf --allow-domains '*' -- node agent.js
β DO: Specific domains only
awf --allow-domains api.github.com,api.openai.com -- node agent.js
- Use API Proxy for Credentials
β DON'T: Expose tokens to agent
const token = process.env.OPENAI_API_KEY; // Visible to agent
β DO: Use API proxy
awf --api-proxy -- node agent.js # Tokens in proxy only
- Monitor and Audit
Enable comprehensive logging:
awf --log-level debug
--audit-log /var/log/awf/audit.log
--allow-domains github.com
-- python agent.py
Review logs regularly:
Daily review
grep "TCP_DENIED" /var/log/squid/access.log | wc -l
Alert on suspicious patterns
grep "evil.com" /var/log/squid/access.log && notify-admin
- Test Firewall Rules
Verify blocking:
Should succeed
awf --allow-domains github.com -- curl https://api.github.com
Should fail
awf --allow-domains github.com -- curl https://evil.com
- Performance Optimization
Enable caching:
cache_mem 512 MB maximum_object_size 100 MB cache_dir ufs /var/spool/squid 10000 16 256
Use connection pooling:
persistent_connection_timeout 60 seconds client_persistent_connections on server_persistent_connections on
- Security Hardening
Disable unnecessary features:
No FTP
acl FTP proto FTP http_access deny FTP
No HTTPS without SSL Bump
acl SSL_ports port 443 http_access deny CONNECT !SSL_ports
Regular updates:
Update Squid
docker pull ubuntu/squid:latest
Update AWF
npm update -g gh-aw-firewall
π Related Skills
-
gh-aw-safe-outputs - Controlled write operations
-
gh-aw-mcp-gateway - MCP server routing
-
gh-aw-security-architecture - Overall security model
-
gh-aw-containerization - Docker patterns
-
gh-aw-authentication-credentials - Credential management
π References
-
AWF Repository
-
Quickstart Guide
-
Chroot Mode
-
API Proxy Sidecar
-
GitHub Actions Integration
-
Squid Documentation
β Remember
-
β AWF provides L7 domain whitelisting
-
β iptables enforces rules at host level
-
β Three modes: Standard, Chroot, API Proxy
-
β Use API proxy for credential isolation
-
β SSL Bump enables HTTPS inspection
-
β Monitor logs for security events
-
β Test firewall rules before production
-
β Principle of least privilege (minimal domains)
-
β Regular security updates
-
β Works transparently with containers
Version: 1.0.0
Last Updated: 2026-02-17
Maintained by: Hack23 AB