Skip to content

CLI Reference

Quick reference for the awf command-line interface.

Terminal window
awf [options] -- <command>
Option Type Default Description
--config <path> string — Path to AWF JSON/YAML config file (use - to read from stdin)
--allow-domains <domains> string — Comma-separated list of allowed domains (optional; if not specified, all network access is blocked)
--allow-domains-file <path> string — Path to file containing allowed domains
--ruleset-file <path> string [] YAML rule file for domain allowlisting (repeatable)
--block-domains <domains> string — Comma-separated list of blocked domains (takes precedence over allowed)
--block-domains-file <path> string — Path to file containing blocked domains
--ssl-bump flag false Enable SSL Bump for HTTPS content inspection
--allow-urls <urls> string — Comma-separated list of allowed URL patterns (requires --ssl-bump)
--log-level <level> string info Logging verbosity: debug, info, warn, error
--keep-containers flag false Keep containers running after command exits
--agent-timeout <minutes> number no limit Maximum time in minutes for the agent command to run
--tty flag false Allocate pseudo-TTY for interactive tools
--work-dir <dir> string /tmp/awf-<timestamp> Working directory for temporary files
--build-local flag false Build containers locally instead of pulling from registry
--image-registry <url> string ghcr.io/github/gh-aw-firewall Container image registry
--image-tag <tag> string latest Container image tag. Supports optional per-image digest pinning: <tag>,squid=sha256:...,agent=sha256:...,agent-act=sha256:...,api-proxy=sha256:...,cli-proxy=sha256:...
--skip-pull flag false Use local images without pulling from registry
--docker-host <socket> string auto-detected Docker socket for AWF’s own containers
-e, --env <KEY=VALUE> string [] Environment variable (repeatable)
--env-all flag false Pass all host environment variables
--exclude-env <name> string [] Exclude a variable from --env-all passthrough (repeatable)
--env-file <path> string — Read env vars from a file (KEY=VALUE format, one per line)
-v, --mount <host:container[:mode]> string [] Volume mount (repeatable)
--container-workdir <dir> string User home Working directory inside container
--memory-limit <limit> string 6g Memory limit for the agent container
--dns-servers <servers> string Auto-detected Trusted DNS servers (comma-separated; auto-detected from host, falls back to 8.8.8.8,8.8.4.4)
--dns-over-https [resolver-url] optional string https://dns.google/dns-query Enable DNS-over-HTTPS via sidecar proxy
--upstream-proxy <url> string auto-detected Upstream (corporate) proxy URL for Squid to chain through
--proxy-logs-dir <path> string — Directory to save Squid proxy logs to
--audit-dir <path> string — Directory for firewall audit artifacts
--session-state-dir <path> string — Directory to save Copilot CLI session state
--enable-host-access flag false Enable access to host services via host.docker.internal
--allow-host-ports <ports> string 80,443 Ports to allow when using –enable-host-access
--allow-host-service-ports <ports> string — Ports to allow ONLY to host gateway (for GitHub Actions services:)
--enable-dind flag false Enable Docker-in-Docker by exposing host Docker socket
--enable-dlp flag false Enable DLP scanning to block credential exfiltration
--agent-image <value> string default Agent container image (default, act, or custom)
--enable-api-proxy flag false Enable API proxy sidecar for secure credential injection
--copilot-api-target <host> string api.githubcopilot.com Target hostname for Copilot API requests
--openai-api-target <host> string api.openai.com Target hostname for OpenAI API requests
--openai-api-base-path <path> string — Base path prefix for OpenAI API requests
--api-proxy-ca-cert <path> string — Additional CA certificate for api-proxy upstream TLS verification
--anthropic-api-target <host> string api.anthropic.com Target hostname for Anthropic API requests
--anthropic-api-base-path <path> string — Base path prefix for Anthropic API requests
--gemini-api-target <host> string generativelanguage.googleapis.com Target hostname for Gemini API requests
--gemini-api-base-path <path> string — Base path prefix for Gemini API requests
--rate-limit-rpm <n> number 600 Max requests per minute per provider
--rate-limit-rph <n> number 10000 Max requests per hour per provider
--rate-limit-bytes-pm <n> number 52428800 (~50 MB) Max request bytes per minute per provider
--no-rate-limit flag — Disable rate limiting in API proxy
--enable-token-steering flag false Inject budget-warning messages at 80/90/95/99% effective token usage
--difc-proxy-host <host:port> string — Connect to external DIFC proxy and enable CLI proxy sidecar
--difc-proxy-ca-cert <path> string — Path to TLS CA cert for external DIFC proxy verification
--diagnostic-logs flag false Collect diagnostics on non-zero exit
-V, --version flag — Display version
-h, --help flag — Display help

Load AWF options from a JSON or YAML config file. Use - to read config from stdin.

CLI flags always take precedence over values loaded from the config file.

Terminal window
# Load from file
sudo awf --config ./awf.yml -- curl https://api.github.com
# Load from stdin
cat awf.yml | sudo awf --config - -- curl https://api.github.com

Comma-separated list of allowed domains. Domains automatically match all subdomains. Supports wildcard patterns, protocol-specific filtering, and special keywords.

If no domains are specified, all network access is blocked. This is useful for running commands that should have no network access.

Terminal window
# Allow specific domains
--allow-domains github.com,npmjs.org
--allow-domains '*.github.com,api-*.example.com'
# No network access (empty or omitted)
awf -- echo "offline command"

Restrict domains to HTTP-only or HTTPS-only traffic by prefixing with the protocol:

Terminal window
# HTTPS only - blocks HTTP traffic to this domain
--allow-domains 'https://secure.example.com'
# HTTP only - blocks HTTPS traffic to this domain
--allow-domains 'http://legacy-api.example.com'
# Both protocols (default behavior)
--allow-domains 'example.com'
# Mixed configuration
--allow-domains 'example.com,https://secure.example.com,http://legacy.example.com'
# Works with wildcards
--allow-domains 'https://*.secure.example.com'
Format HTTP HTTPS Example
domain.com ✓ ✓ --allow-domains example.com
https://domain.com ✗ ✓ --allow-domains 'https://api.example.com'
http://domain.com ✓ ✗ --allow-domains 'http://legacy.example.com'

Use * to match multiple domains:

Terminal window
# Match any subdomain
--allow-domains '*.github.com'
# Match prefix patterns within a subdomain label
--allow-domains 'api-*.example.com'
# Combine plain domains and wildcards
--allow-domains 'github.com,*.googleapis.com,api-*.example.com'
Pattern Matches Does Not Match
*.github.com api.github.com, raw.github.com github.com
api-*.example.com api-v1.example.com, api-test.example.com api.example.com
github.com github.com, api.github.com notgithub.com

Security restrictions: Overly broad patterns like *, *.*, or *.*.* are rejected.

Using localhost in --allow-domains triggers special behavior for local development:

Terminal window
# Automatically configures everything for local testing
sudo awf --allow-domains localhost -- npx playwright test

When localhost is detected, awf automatically:

  1. Replaces localhost with host.docker.internal — Maps to Docker’s host gateway so containers can reach host services
  2. Enables --enable-host-access — Activates host network access (equivalent to passing --enable-host-access)
  3. Allows common development ports — Opens ports 3000, 3001, 4000, 4200, 5000, 5173, 8000, 8080, 8081, 8888, 9000, 9090

Protocol prefixes are preserved: http://localhost becomes http://host.docker.internal and https://localhost becomes https://host.docker.internal.

Terminal window
# Override the default ports
sudo awf --allow-domains localhost --allow-host-ports 3000,8080 -- npx playwright test
# Combine with other domains
sudo awf --allow-domains localhost,github.com -- npx playwright test

See also: Playwright Testing with Localhost for detailed examples.

Path to file with allowed domains. Supports comments (#) and one domain per line.

Terminal window
--allow-domains-file ./allowed-domains.txt

YAML rule file for domain allowlisting. Can be specified multiple times to load multiple files. Domains from ruleset files are merged with --allow-domains and --allow-domains-file.

Terminal window
# Single ruleset file
--ruleset-file ./domains.yml
# Multiple ruleset files
--ruleset-file ./base-domains.yml --ruleset-file ./extra-domains.yml

Schema (version 1):

version: 1
rules:
- domain: github.com
subdomains: true # default: true — also allows *.github.com
- domain: example.com
subdomains: false # exact match only

Fields:

  • version — Must be 1
  • rules — Array of rule objects

Each rule has the following fields:

Field Required Default Description
domain Yes — Domain name to allow
subdomains No true Whether to also allow all subdomains

Comma-separated list of blocked domains. Blocked domains take precedence over allowed domains, enabling fine-grained control. Supports the same wildcard patterns as --allow-domains.

Terminal window
# Block specific subdomain while allowing parent domain
--allow-domains example.com --block-domains internal.example.com
# Block with wildcards
--allow-domains '*.example.com' --block-domains '*.secret.example.com'

Path to file with blocked domains. Supports the same format as --allow-domains-file.

Terminal window
--block-domains-file ./blocked-domains.txt

Enable SSL Bump for HTTPS content inspection. When enabled, the firewall generates a per-session CA certificate and intercepts HTTPS connections, allowing URL path filtering.

Terminal window
--ssl-bump --allow-urls "https://github.com/myorg/*"

How it works:

  1. A unique CA certificate is generated (valid for 1 day)
  2. The CA is injected into the agent container’s trust store
  3. Squid intercepts HTTPS using SSL Bump (peek, stare, bump)
  4. Full URLs become visible for filtering via --allow-urls

See also: SSL Bump Reference for complete documentation.

Comma-separated list of allowed URL patterns for HTTPS traffic. Requires --ssl-bump.

Terminal window
# Single pattern
--allow-urls "https://github.com/myorg/*"
# Multiple patterns
--allow-urls "https://github.com/org1/*,https://api.github.com/repos/*"

Pattern syntax:

  • Must include scheme (https://)
  • * matches any characters in a path segment
  • Patterns are matched against the full request URL

Set logging verbosity.

Level Description
debug Detailed information including config, container startup, iptables rules
info Normal operational messages (default)
warn Warning messages
error Error messages only

Keep containers and configuration files after command exits for debugging.

Maximum time in minutes for the agent command to run. When the timeout is reached, the agent container is stopped and the firewall exits. Must be a positive integer.

Terminal window
# Allow up to 30 minutes
sudo awf --agent-timeout 30 --allow-domains github.com \
-- long-running-command
# Allow up to 2 hours
sudo awf --agent-timeout 120 --allow-domains github.com \
-- npx @github/copilot@latest --prompt "complex task"

Allocate a pseudo-TTY for interactive tools (e.g., Claude Code, interactive shells).

Custom working directory for temporary files. Contains squid.conf, docker-compose.yml, and log directories.

Build containers from local Dockerfiles instead of pulling pre-built images.

Custom container image registry URL.

Container image tag to use. Supports an optional digest-aware format for cryptographic image pinning:

<tag>,squid=sha256:...,agent=sha256:...,agent-act=sha256:...,api-proxy=sha256:...,cli-proxy=sha256:...

Digest keys correspond to each runtime container image. When a digest is provided, the image reference is pinned to <registry>/<image>:<tag>@<digest>, preventing tag mutation attacks. The setup action’s image-tag output produces this format automatically when pull-images: true is set.

Which agent image key is used depends on the --agent-image preset:

  • default → agent
  • act → agent-act

Use local images without pulling from the registry. This is useful for:

  • Air-gapped environments where registry access is unavailable
  • CI systems with pre-warmed image caches to avoid unnecessary network calls
  • Local development when images are already cached
Terminal window
# Pre-pull images first
docker pull ghcr.io/github/gh-aw-firewall/squid:latest
docker pull ghcr.io/github/gh-aw-firewall/agent:latest
# Use with --skip-pull to avoid re-pulling
sudo awf --skip-pull --allow-domains github.com -- curl https://api.github.com

Override the Docker socket used by AWF for its own container operations.

Terminal window
sudo awf --docker-host unix:///run/user/1000/docker.sock \
--allow-domains github.com \
-- curl https://api.github.com

The value must be a unix:// socket URI.

Pass environment variable to container. Can be specified multiple times.

Terminal window
-e API_KEY=secret -e DEBUG=true

Pass all host environment variables to container.

Exclude a specific environment variable from --env-all passthrough. Can be specified multiple times. Only meaningful when used with --env-all.

Terminal window
# Pass all env vars except secrets
sudo -E awf --env-all \
--exclude-env AWS_SECRET_ACCESS_KEY \
--exclude-env GITHUB_TOKEN \
--allow-domains github.com \
-- my-command

Read environment variables from a file. The file uses KEY=VALUE format with one variable per line. Lines starting with # are treated as comments.

Terminal window
sudo awf --env-file ./env.production \
--allow-domains github.com \
-- my-command

File format:

Terminal window
# Database configuration
DB_HOST=localhost
DB_PORT=5432
# API settings
API_KEY=your-api-key-here
DEBUG=true

-v, --mount <host_path:container_path[:mode]>

Section titled “-v, --mount <host_path:container_path[:mode]>”

Mount host directories into container. Format: host_path:container_path[:ro|rw]

Terminal window
-v /data:/data:ro -v /tmp/output:/output:rw

Requirements:

  • Both paths must be absolute
  • Host path must exist
  • Mode: ro (read-only) or rw (read-write)

Default mounts (selective bind mounts, not a blanket host FS mount):

  • System binaries (/usr, /bin, /sbin, /lib, /lib64, /opt, /sys, /dev) at /host (read-only)
  • Workspace and /tmp (read-write)
  • Whitelisted $HOME subdirs such as .cache, .config, .local (read-write)
  • Select /etc files only — SSL certs, passwd, group, etc. (not /etc/shadow)

Working directory inside the container.

Memory limit for the agent container. Format: <number><unit> where unit is b (bytes), k (kilobytes), m (megabytes), or g (gigabytes).

  • Default: 6g
Terminal window
# Increase memory for large language model agents
sudo awf --memory-limit 8g --allow-domains github.com \
-- memory-intensive-command
# Reduce memory for lightweight tasks
sudo awf --memory-limit 2g --allow-domains github.com \
-- curl https://api.github.com

Comma-separated list of trusted DNS servers. DNS traffic is only allowed to these servers, preventing DNS-based data exfiltration. Both IPv4 and IPv6 addresses are supported.

If omitted, DNS servers are auto-detected from host resolvers (e.g., /run/systemd/resolve/resolv.conf or /etc/resolv.conf). Falls back to Google DNS (8.8.8.8, 8.8.4.4) only if auto-detection fails.

Terminal window
# Use Cloudflare DNS
--dns-servers 1.1.1.1,1.0.0.1
# Use Google DNS with IPv6
--dns-servers 8.8.8.8,2001:4860:4860::8888

Enable DNS-over-HTTPS (DoH) via a sidecar proxy. When enabled, DNS queries are encrypted and sent over HTTPS instead of plaintext UDP, preventing DNS-based traffic inspection or tampering.

Terminal window
# Use default resolver (Google DNS)
--dns-over-https
# Use a custom resolver
--dns-over-https https://cloudflare-dns.com/dns-query
  • Default resolver: https://dns.google/dns-query
  • Requirement: Resolver URL must start with https://

Configure Squid to chain outbound traffic through an upstream corporate proxy.

Terminal window
sudo awf --upstream-proxy http://proxy.corp.com:3128 \
--allow-domains github.com \
-- curl https://api.github.com

If omitted, AWF auto-detects host https_proxy/http_proxy settings.

Enable access to host services via host.docker.internal. This allows containers to connect to services running on the host machine (e.g., local development servers, MCP gateways).

Terminal window
# Access local development server
sudo awf --enable-host-access --allow-domains host.docker.internal \
-- curl http://host.docker.internal:3000

See also: Host Access Configuration

Specify which ports are allowed when using --enable-host-access. Accepts comma-separated port numbers or ranges.

Terminal window
# Allow specific ports
--allow-host-ports 3000,8080
# Allow port ranges
--allow-host-ports 3000-3010,8000-8090
# Combine with localhost keyword for Playwright testing
sudo awf --allow-domains localhost --allow-host-ports 3000 \
-- npx playwright test

Default behavior:

  • Without --allow-host-ports: Only ports 80 and 443 are allowed
  • With --allow-host-ports: Only the specified ports are allowed

Comma-separated ports to allow only to the host gateway (host.docker.internal). Designed for GitHub Actions services: containers (e.g., PostgreSQL, Redis) whose ports are exposed to the host gateway.

Terminal window
# Allow PostgreSQL and Redis on host gateway
sudo awf --allow-host-service-ports 5432,6379 \
--allow-domains github.com \
-- python run_tests.py

Key differences from --allow-host-ports:

--allow-host-ports --allow-host-service-ports
Scope General host access Host gateway only
Dangerous ports Blocked (SSH, SMTP, etc.) Allowed (restricted to host)
Requires --enable-host-access Yes No (auto-enables it)
Use case Local dev servers GitHub Actions services:
  • Auto-enables host access: No need to also pass --enable-host-access
  • Bypasses dangerous port restrictions: Ports like 5432 (PostgreSQL) and 6379 (Redis) are normally blocked when using --allow-host-ports to prevent unintended database access, but are safe with --allow-host-service-ports because traffic is restricted to the host gateway only

Save Squid proxy logs directly to a custom directory instead of the default temporary location. Useful for preserving logs across multiple runs or integrating with log aggregation systems.

Terminal window
# Save logs to custom directory
sudo awf --proxy-logs-dir ./firewall-logs \
--allow-domains github.com \
-- curl https://api.github.com
# Check logs
cat ./firewall-logs/access.log

Note: The directory must be writable by the current user.

Directory for firewall audit artifacts. When specified, the firewall saves configuration files, the policy manifest, and iptables state to this directory for compliance and debugging purposes.

Terminal window
# Save audit artifacts
sudo awf --audit-dir ./audit \
--allow-domains github.com \
-- curl https://api.github.com
# Review audit artifacts
ls ./audit/

Directory to persist Copilot CLI session state (such as events.jsonl) during execution.

Terminal window
sudo awf --session-state-dir ./session-state \
--allow-domains github.com \
-- copilot --prompt "hello"

Specify the agent container image to use. Supports pre-built presets or custom base images.

Presets (pre-built, pull from GHCR):

  • default — Minimal ubuntu:22.04 (~200MB, fast startup)
  • act — GitHub Actions parity (~2GB, includes all runner tools)

Custom base images (requires --build-local):

  • ubuntu:XX.XX (e.g., ubuntu:22.04, ubuntu:24.04)
  • ghcr.io/catthehacker/ubuntu:runner-XX.XX
  • ghcr.io/catthehacker/ubuntu:full-XX.XX
  • ghcr.io/catthehacker/ubuntu:act-XX.XX
Terminal window
# Use default preset (minimal, fast)
sudo awf --allow-domains github.com -- curl https://api.github.com
# Use act preset (GitHub Actions compatible)
sudo awf --agent-image act --allow-domains github.com \
-- curl https://api.github.com
# Use custom base image (requires --build-local)
sudo awf --agent-image ubuntu:24.04 --build-local \
--allow-domains github.com \
-- curl https://api.github.com

See also: Agent Images Reference

Enable Docker-in-Docker by mounting the host Docker socket (/var/run/docker.sock) into the agent container. This allows the agent to run Docker commands.

Terminal window
sudo awf --enable-dind --allow-domains github.com \
-- docker run hello-world

Enable Data Loss Prevention (DLP) scanning on outbound requests. When enabled, the firewall inspects outbound request URLs for patterns that match common credentials (API keys, tokens, passwords) and blocks requests that appear to exfiltrate secrets.

Terminal window
sudo awf --enable-dlp --allow-domains github.com \
-- python my_script.py

Enable the API proxy sidecar for secure credential injection. The sidecar is a Node.js proxy (172.30.0.30) that holds real API credentials so the agent never sees them. The agent sends unauthenticated requests to the sidecar, which injects the credentials and forwards the request through Squid to the upstream API.

Terminal window
# Enable with keys from environment
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
sudo -E awf --enable-api-proxy \
--allow-domains api.openai.com,api.anthropic.com \
-- command

Required environment variables (at least one):

Variable Provider
OPENAI_API_KEY OpenAI / Codex
ANTHROPIC_API_KEY Anthropic / Claude
COPILOT_GITHUB_TOKEN GitHub Copilot
COPILOT_PROVIDER_API_KEY GitHub Copilot BYOK provider (Azure / OpenRouter / etc.)
GEMINI_API_KEY Google Gemini

Sidecar ports:

Port Provider
10000 OpenAI
10001 Anthropic
10002 GitHub Copilot
10003 Google Gemini

Target hostname for GitHub Copilot API requests. Useful for GitHub Enterprise Server (GHES) deployments where the Copilot API endpoint differs from the public default. Can also be set via the COPILOT_API_TARGET environment variable.

  • Default: api.githubcopilot.com
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--copilot-api-target api.github.mycompany.com \
--allow-domains api.github.mycompany.com \
-- command

Target hostname for OpenAI API requests. Useful for custom OpenAI-compatible endpoints such as Azure OpenAI, internal LLM routers, vLLM, or TGI. Can also be set via the OPENAI_API_TARGET environment variable.

  • Default: api.openai.com
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--openai-api-target llm-router.internal.example.com \
--allow-domains llm-router.internal.example.com \
-- command

Name of a runner environment variable (typically bound to a secret) whose value is the base URL of a private OpenAI-compatible endpoint. AWF reads and validates the URL on the runner before any container starts, derives the upstream host and base path for the api-proxy sidecar, adds the host to the Squid policy, excludes the variable from the agent environment, and redacts the URL/host/host:port forms from logs and audit artifacts.

The value must be an absolute https:// URL without credentials, query string, fragment, or a non-default port. Invalid or missing values fail before agent startup with an error that does not echo the value.

Config path: apiProxy.targets.openai.baseUrlEnv. Takes precedence over --openai-api-target / --openai-api-base-path.

  • Default: none
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--openai-base-url-env CODEX_LB_BASE_URL \
-- codex exec "..."

Base path prefix prepended to every upstream OpenAI API request path. Use this when the upstream endpoint requires a URL prefix (e.g., Databricks serving endpoints, Azure OpenAI deployments). Can also be set via the OPENAI_API_BASE_PATH environment variable.

  • Default: none
  • Requires: --enable-api-proxy
Terminal window
# Databricks serving endpoint
sudo -E awf --enable-api-proxy \
--openai-api-target myworkspace.cloud.databricks.com \
--openai-api-base-path /serving-endpoints \
--allow-domains myworkspace.cloud.databricks.com \
-- command

Path to an additional CA certificate used by the api-proxy sidecar when verifying TLS for custom upstream provider targets. AWF bind-mounts the file read-only into the sidecar and sets NODE_EXTRA_CA_CERTS; Node’s built-in roots remain trusted.

  • Default: none
  • Requires: API proxy sidecar
Terminal window
sudo -E awf \
--openai-api-target llm-router.internal.example.com \
--api-proxy-ca-cert /etc/ssl/certs/corporate-ca.crt \
--allow-domains llm-router.internal.example.com \
-- command

Target hostname for Anthropic API requests. Useful for custom Anthropic-compatible endpoints such as internal LLM routers. Can also be set via the ANTHROPIC_API_TARGET environment variable.

  • Default: api.anthropic.com
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--anthropic-api-target llm-router.internal.example.com \
--allow-domains llm-router.internal.example.com \
-- command

Base path prefix prepended to every upstream Anthropic API request path. Use this when the upstream endpoint requires a URL prefix. Can also be set via the ANTHROPIC_API_BASE_PATH environment variable.

  • Default: none
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--anthropic-api-target custom-llm.example.com \
--anthropic-api-base-path /anthropic \
--allow-domains custom-llm.example.com \
-- command

Target hostname for Gemini API requests. Useful for private gateways or compatible Gemini endpoints.

  • Default: generativelanguage.googleapis.com
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--gemini-api-target ai-gateway.internal.example.com \
--allow-domains ai-gateway.internal.example.com \
-- command

Base path prefix prepended to Gemini API requests.

  • Default: none
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--gemini-api-target ai-gateway.internal.example.com \
--gemini-api-base-path /gemini \
--allow-domains ai-gateway.internal.example.com \
-- command

Maximum number of requests per minute per provider. Rate limiting is opt-in — it is only enabled when at least one --rate-limit-* flag is provided.

  • Default: 600 (when rate limiting is enabled)
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--rate-limit-rpm 100 \
--allow-domains api.openai.com \
-- command

Maximum number of requests per hour per provider.

  • Default: 10000 (when rate limiting is enabled)
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--rate-limit-rph 5000 \
--allow-domains api.anthropic.com \
-- command

Maximum request bytes per minute per provider.

  • Default: 52428800 (~50 MB, when rate limiting is enabled)
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--rate-limit-bytes-pm 10485760 \
--allow-domains api.openai.com \
-- command

Explicitly disable rate limiting in the API proxy, even if other --rate-limit-* flags are provided. Useful for overriding defaults in scripts or CI configurations.

  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy --no-rate-limit \
--allow-domains api.anthropic.com \
-- command

Inject budget-warning system messages into outgoing LLM requests when cumulative effective token usage crosses 80%, 90%, 95%, or 99% of maxEffectiveTokens. Each threshold is injected at most once per run. Has no effect if maxEffectiveTokens is not configured.

  • Default: false
  • Requires: --enable-api-proxy
Terminal window
sudo -E awf --enable-api-proxy \
--enable-token-steering \
--allow-domains api.anthropic.com \
-- command

Connect to an external DIFC proxy (mcpg) and enable the CLI proxy sidecar for gh command routing.

Terminal window
sudo awf --difc-proxy-host 127.0.0.1:5555 \
--allow-domains github.com \
-- gh repo view github/gh-aw-firewall

Path to a CA certificate written by the external DIFC proxy. Recommended when using --difc-proxy-host over TLS.

Terminal window
sudo awf --difc-proxy-host 127.0.0.1:5555 \
--difc-proxy-ca-cert /tmp/mcpg-ca.crt \
--allow-domains github.com \
-- gh repo view github/gh-aw-firewall

Collect container logs, exit state, and a sanitized config snapshot when the wrapped command exits non-zero.

Diagnostic artifacts are written to <workDir>/diagnostics/ (or <audit-dir>/diagnostics/ when --audit-dir is set).

AWF automatically detects GitHub Enterprise environments and adds required domains to the allowlist. No manual configuration is needed — the domains are auto-added when the relevant environment variables are present.

When GITHUB_SERVER_URL points to a *.ghe.com tenant (set automatically by GitHub Agentic Workflows), AWF auto-adds:

Auto-added Domain Purpose
<tenant>.ghe.com Enterprise tenant
api.<tenant>.ghe.com API access
copilot-api.<tenant>.ghe.com Copilot inference
copilot-telemetry-service.<tenant>.ghe.com Copilot telemetry

Domains from GITHUB_API_URL are also detected — if GITHUB_API_URL points to a *.ghe.com hostname (e.g., https://api.myorg.ghe.com), that hostname is added to the allowlist as well. This ensures API access works even if only GITHUB_API_URL is set.

Terminal window
# These environment variables are set automatically by GitHub Agentic Workflows
# GITHUB_SERVER_URL=https://myorg.ghe.com
# GITHUB_API_URL=https://api.myorg.ghe.com
# AWF auto-adds:
# - myorg.ghe.com
# - api.myorg.ghe.com
# - copilot-api.myorg.ghe.com
# - copilot-telemetry-service.myorg.ghe.com
sudo awf --allow-domains github.com -- copilot-agent

When ENGINE_API_TARGET is set (indicating a GHES environment), AWF auto-adds:

Auto-added Domain Purpose
github.<company>.com GHES base domain (extracted from API URL)
api.github.<company>.com GHES API access
api.githubcopilot.com Copilot API (cloud-hosted)
api.enterprise.githubcopilot.com Enterprise Copilot API
telemetry.enterprise.githubcopilot.com Enterprise Copilot telemetry
Terminal window
# Set by GitHub Agentic Workflows on GHES
# ENGINE_API_TARGET=https://api.github.mycompany.com
# AWF auto-adds:
# - github.mycompany.com
# - api.github.mycompany.com
# - api.githubcopilot.com
# - api.enterprise.githubcopilot.com
# - telemetry.enterprise.githubcopilot.com
sudo awf --allow-domains github.com -- copilot-agent

AWF reads several environment variables that influence its behavior. These are grouped by purpose.

These variables supply API credentials to the API proxy sidecar when --enable-api-proxy is active.

Variable Description
OPENAI_API_KEY OpenAI API key — held securely in the api-proxy sidecar
ANTHROPIC_API_KEY Anthropic API key — held securely in the api-proxy sidecar
COPILOT_GITHUB_TOKEN GitHub Copilot token — held securely in the api-proxy sidecar
COPILOT_PROVIDER_API_KEY GitHub Copilot BYOK provider API key — held securely in the api-proxy sidecar

These variables provide an alternative to the corresponding CLI flags for configuring API proxy endpoints. The CLI flag takes precedence if both are set.

Variable Default Description
COPILOT_API_TARGET api.githubcopilot.com Copilot API endpoint override
OPENAI_API_TARGET api.openai.com OpenAI API endpoint override
OPENAI_API_BASE_PATH (empty) OpenAI API base path (e.g., /serving-endpoints)
OPENAI_BASE_URL_ENV (unset) Name of the runner variable holding a secret OpenAI-compatible base URL (see --openai-base-url-env)
ANTHROPIC_API_TARGET api.anthropic.com Anthropic API endpoint override
ANTHROPIC_API_BASE_PATH (empty) Anthropic API base path
Variable CLI Flag Description
AWF_AUDIT_DIR --audit-dir Directory for audit artifacts
Code Description
0 Command succeeded
1-255 Command exit code or firewall error
130 Interrupted by SIGINT (Ctrl+C)
143 Terminated by SIGTERM

Pre-download Docker images for offline use or faster startup. This pulls container images ahead of time so that subsequent awf runs can use --skip-pull to avoid network calls.

Terminal window
awf predownload [options]
Option Type Default Description
--image-registry <registry> string ghcr.io/github/gh-aw-firewall Container image registry
--image-tag <tag> string latest Container image tag (applies to squid, agent, agent-act, api-proxy, and cli-proxy images). Supports optional digest metadata — see --image-tag for format details.
--agent-image <value> string default Agent image preset (default, act) or custom image
--enable-api-proxy flag false Also download the API proxy image
--difc-proxy flag false Also download the CLI proxy image used when runtime flag --difc-proxy-host is set
Terminal window
# Pre-download default images (squid + agent)
awf predownload
# Pre-download including the API proxy image
awf predownload --enable-api-proxy
# Pre-download including the CLI proxy image
awf predownload --difc-proxy
# Pre-download a specific version
awf predownload --image-tag v0.3.0
# Pre-download the act (GitHub Actions parity) agent image
awf predownload --agent-image act
# Use a custom registry
awf predownload --image-registry ghcr.io/myorg/awf
# After pre-downloading, run without pulling
sudo awf --skip-pull --allow-domains github.com -- curl https://api.github.com

View Squid proxy logs from current or previous runs.

Terminal window
awf logs [options]
Option Type Default Description
-f, --follow flag false Follow log output in real-time
--format <format> string pretty Output format: raw, pretty, json
--source <path> string auto Path to log directory or running for live container
--list flag false List available log sources
--with-pid flag false Enrich logs with PID/process info (requires -f)
Format Description
pretty Colorized, human-readable output (default)
raw Logs as-is without parsing
json Structured JSON for scripting
Terminal window
# View recent logs with pretty formatting
awf logs
# Follow logs in real-time
awf logs -f
# View logs in JSON format
awf logs --format json
# List available log sources
awf logs --list
# Use a specific log directory
awf logs --source /tmp/squid-logs-1234567890
# Stream from running container
awf logs --source running -f
# Follow logs with PID/process tracking
awf logs -f --with-pid

The --with-pid flag enriches log entries with process information, correlating each network request to the specific process that made it.

Pretty format with PID:

[2024-01-01 12:00:00.123] CONNECT api.github.com → 200 (ALLOWED) [curl/7.88.1] <PID:12345 curl>

JSON output includes additional fields:

{
"timestamp": 1703001234.567,
"domain": "github.com",
"pid": 12345,
"cmdline": "curl https://github.com",
"comm": "curl",
"inode": "123456"
}

Show aggregated statistics from firewall logs.

Terminal window
awf logs stats [options]
Option Type Default Description
--format <format> string pretty Output format: json, markdown, pretty
--source <path> string auto Path to log directory or running for live container
Format Description
pretty Colorized terminal output with summary and domain breakdown (default)
markdown Markdown table format suitable for documentation
json Structured JSON for programmatic consumption
Terminal window
# Show stats with colorized terminal output
awf logs stats
# Get stats in JSON format for scripting
awf logs stats --format json
# Get stats in markdown format
awf logs stats --format markdown
# Use a specific log directory
awf logs stats --source /tmp/squid-logs-1234567890
Firewall Statistics
────────────────────────────────────────
Total Requests: 150
Allowed: 145 (96.7%)
Denied: 5 (3.3%)
Unique Domains: 12
Domains:
api.github.com 50 allowed, 0 denied
registry.npmjs.org 95 allowed, 0 denied
evil.com 0 allowed, 5 denied

Generate summary report optimized for GitHub Actions step summaries.

Terminal window
awf logs summary [options]
Option Type Default Description
--format <format> string markdown Output format: json, markdown, pretty
--source <path> string auto Path to log directory or running for live container
Terminal window
# Generate markdown summary (default)
awf logs summary
# Add to GitHub Actions step summary
awf logs summary >> $GITHUB_STEP_SUMMARY
# Get summary in JSON format
awf logs summary --format json
# Get summary with colorized terminal output
awf logs summary --format pretty
<details>
<summary>Firewall Activity</summary>
▼ 150 requests | 145 allowed | 5 blocked | 12 unique domains
| Domain | Allowed | Denied |
|--------|---------|--------|
| api.github.com | 50 | 0 |
| registry.npmjs.org | 95 | 0 |
| evil.com | 0 | 5 |
</details>

Show firewall audit with policy rule matching. Enriches log entries with the specific policy rule that caused each allow/deny decision.

Terminal window
awf logs audit [options]
Option Type Default Description
--format <format> string pretty Output format: json, markdown, pretty
--source <path> string auto Path to log directory or running for live container
--rule <id> string — Filter to a specific rule ID
--domain <domain> string — Filter to a specific domain
--decision <decision> string — Filter to allowed or denied
Terminal window
# Show audit report with colorized terminal output
awf logs audit
# Show audit in JSON format
awf logs audit --format json
# Generate markdown audit report
awf logs audit --format markdown
# Filter to denied requests only
awf logs audit --decision denied
# Filter to a specific domain
awf logs audit --domain github.com
# Filter by rule ID
awf logs audit --rule allow-both-plain
# Use a specific log directory
awf logs audit --source /tmp/squid-logs-1234567890
Firewall Audit Report
────────────────────────────────────────────────────────────
Rule Evaluation:
allow-both-plain allow 12 hits Allow domain (HTTP+HTTPS)
default-deny deny 3 hits Default deny rule
Denied Requests (3):
12:00:01.234 evil.com → default-deny
12:00:02.567 malware.org → default-deny
12:00:03.890 blocked.net → default-deny