CLI Reference
Quick reference for the awf command-line interface.
Synopsis
Section titled “Synopsis”awf [options] -- <command>Options Summary
Section titled “Options Summary”| 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 |
Options Details
Section titled “Options Details”--config <path>
Section titled “--config <path>”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.
# Load from filesudo awf --config ./awf.yml -- curl https://api.github.com
# Load from stdincat awf.yml | sudo awf --config - -- curl https://api.github.com--allow-domains <domains>
Section titled “--allow-domains <domains>”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.
# 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"Protocol-specific filtering
Section titled “Protocol-specific filtering”Restrict domains to HTTP-only or HTTPS-only traffic by prefixing with the protocol:
# 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' |
Wildcard patterns
Section titled “Wildcard patterns”Use * to match multiple domains:
# 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.
localhost keyword
Section titled “localhost keyword”Using localhost in --allow-domains triggers special behavior for local development:
# Automatically configures everything for local testingsudo awf --allow-domains localhost -- npx playwright testWhen localhost is detected, awf automatically:
- Replaces
localhostwithhost.docker.internal— Maps to Docker’s host gateway so containers can reach host services - Enables
--enable-host-access— Activates host network access (equivalent to passing--enable-host-access) - 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.
# Override the default portssudo awf --allow-domains localhost --allow-host-ports 3000,8080 -- npx playwright test
# Combine with other domainssudo awf --allow-domains localhost,github.com -- npx playwright testSee also: Playwright Testing with Localhost for detailed examples.
--allow-domains-file <path>
Section titled “--allow-domains-file <path>”Path to file with allowed domains. Supports comments (#) and one domain per line.
--allow-domains-file ./allowed-domains.txt--ruleset-file <path>
Section titled “--ruleset-file <path>”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.
# Single ruleset file--ruleset-file ./domains.yml
# Multiple ruleset files--ruleset-file ./base-domains.yml --ruleset-file ./extra-domains.ymlSchema (version 1):
version: 1rules: - domain: github.com subdomains: true # default: true — also allows *.github.com - domain: example.com subdomains: false # exact match onlyFields:
version— Must be1rules— 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 |
--block-domains <domains>
Section titled “--block-domains <domains>”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.
# 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'--block-domains-file <path>
Section titled “--block-domains-file <path>”Path to file with blocked domains. Supports the same format as --allow-domains-file.
--block-domains-file ./blocked-domains.txt--ssl-bump
Section titled “--ssl-bump”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.
--ssl-bump --allow-urls "https://github.com/myorg/*"How it works:
- A unique CA certificate is generated (valid for 1 day)
- The CA is injected into the agent container’s trust store
- Squid intercepts HTTPS using SSL Bump (peek, stare, bump)
- Full URLs become visible for filtering via
--allow-urls
See also: SSL Bump Reference for complete documentation.
--allow-urls <urls>
Section titled “--allow-urls <urls>”Comma-separated list of allowed URL patterns for HTTPS traffic. Requires --ssl-bump.
# 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
--log-level <level>
Section titled “--log-level <level>”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
Section titled “--keep-containers”Keep containers and configuration files after command exits for debugging.
--agent-timeout <minutes>
Section titled “--agent-timeout <minutes>”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.
# Allow up to 30 minutessudo awf --agent-timeout 30 --allow-domains github.com \ -- long-running-command
# Allow up to 2 hourssudo 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).
--work-dir <dir>
Section titled “--work-dir <dir>”Custom working directory for temporary files. Contains squid.conf, docker-compose.yml, and log directories.
--build-local
Section titled “--build-local”Build containers from local Dockerfiles instead of pulling pre-built images.
--image-registry <url>
Section titled “--image-registry <url>”Custom container image registry URL.
--image-tag <tag>
Section titled “--image-tag <tag>”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→agentact→agent-act
--skip-pull
Section titled “--skip-pull”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
# Pre-pull images firstdocker pull ghcr.io/github/gh-aw-firewall/squid:latestdocker pull ghcr.io/github/gh-aw-firewall/agent:latest
# Use with --skip-pull to avoid re-pullingsudo awf --skip-pull --allow-domains github.com -- curl https://api.github.com--docker-host <socket>
Section titled “--docker-host <socket>”Override the Docker socket used by AWF for its own container operations.
sudo awf --docker-host unix:///run/user/1000/docker.sock \ --allow-domains github.com \ -- curl https://api.github.comThe value must be a unix:// socket URI.
-e, --env <KEY=VALUE>
Section titled “-e, --env <KEY=VALUE>”Pass environment variable to container. Can be specified multiple times.
-e API_KEY=secret -e DEBUG=true--env-all
Section titled “--env-all”Pass all host environment variables to container.
--exclude-env <name>
Section titled “--exclude-env <name>”Exclude a specific environment variable from --env-all passthrough. Can be specified multiple times. Only meaningful when used with --env-all.
# Pass all env vars except secretssudo -E awf --env-all \ --exclude-env AWS_SECRET_ACCESS_KEY \ --exclude-env GITHUB_TOKEN \ --allow-domains github.com \ -- my-command--env-file <path>
Section titled “--env-file <path>”Read environment variables from a file. The file uses KEY=VALUE format with one variable per line. Lines starting with # are treated as comments.
sudo awf --env-file ./env.production \ --allow-domains github.com \ -- my-commandFile format:
# Database configurationDB_HOST=localhostDB_PORT=5432
# API settingsAPI_KEY=your-api-key-hereDEBUG=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]
-v /data:/data:ro -v /tmp/output:/output:rwRequirements:
- Both paths must be absolute
- Host path must exist
- Mode:
ro(read-only) orrw(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
$HOMEsubdirs such as.cache,.config,.local(read-write) - Select
/etcfiles only — SSL certs,passwd,group, etc. (not/etc/shadow)
--container-workdir <dir>
Section titled “--container-workdir <dir>”Working directory inside the container.
--memory-limit <limit>
Section titled “--memory-limit <limit>”Memory limit for the agent container. Format: <number><unit> where unit is b (bytes), k (kilobytes), m (megabytes), or g (gigabytes).
- Default:
6g
# Increase memory for large language model agentssudo awf --memory-limit 8g --allow-domains github.com \ -- memory-intensive-command
# Reduce memory for lightweight taskssudo awf --memory-limit 2g --allow-domains github.com \ -- curl https://api.github.com--dns-servers <servers>
Section titled “--dns-servers <servers>”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.
# 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--dns-over-https [resolver-url]
Section titled “--dns-over-https [resolver-url]”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.
# 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://
--upstream-proxy <url>
Section titled “--upstream-proxy <url>”Configure Squid to chain outbound traffic through an upstream corporate proxy.
sudo awf --upstream-proxy http://proxy.corp.com:3128 \ --allow-domains github.com \ -- curl https://api.github.comIf omitted, AWF auto-detects host https_proxy/http_proxy settings.
--enable-host-access
Section titled “--enable-host-access”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).
# Access local development serversudo awf --enable-host-access --allow-domains host.docker.internal \ -- curl http://host.docker.internal:3000See also: Host Access Configuration
--allow-host-ports <ports>
Section titled “--allow-host-ports <ports>”Specify which ports are allowed when using --enable-host-access. Accepts comma-separated port numbers or ranges.
# Allow specific ports--allow-host-ports 3000,8080
# Allow port ranges--allow-host-ports 3000-3010,8000-8090
# Combine with localhost keyword for Playwright testingsudo awf --allow-domains localhost --allow-host-ports 3000 \ -- npx playwright testDefault behavior:
- Without
--allow-host-ports: Only ports 80 and 443 are allowed - With
--allow-host-ports: Only the specified ports are allowed
--allow-host-service-ports <ports>
Section titled “--allow-host-service-ports <ports>”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.
# Allow PostgreSQL and Redis on host gatewaysudo awf --allow-host-service-ports 5432,6379 \ --allow-domains github.com \ -- python run_tests.pyKey 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-portsto prevent unintended database access, but are safe with--allow-host-service-portsbecause traffic is restricted to the host gateway only
--proxy-logs-dir <path>
Section titled “--proxy-logs-dir <path>”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.
# Save logs to custom directorysudo awf --proxy-logs-dir ./firewall-logs \ --allow-domains github.com \ -- curl https://api.github.com
# Check logscat ./firewall-logs/access.logNote: The directory must be writable by the current user.
--audit-dir <path>
Section titled “--audit-dir <path>”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.
# Save audit artifactssudo awf --audit-dir ./audit \ --allow-domains github.com \ -- curl https://api.github.com
# Review audit artifactsls ./audit/--session-state-dir <path>
Section titled “--session-state-dir <path>”Directory to persist Copilot CLI session state (such as events.jsonl) during execution.
sudo awf --session-state-dir ./session-state \ --allow-domains github.com \ -- copilot --prompt "hello"--agent-image <value>
Section titled “--agent-image <value>”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.XXghcr.io/catthehacker/ubuntu:full-XX.XXghcr.io/catthehacker/ubuntu:act-XX.XX
# 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.comSee also: Agent Images Reference
--enable-dind
Section titled “--enable-dind”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.
sudo awf --enable-dind --allow-domains github.com \ -- docker run hello-world--enable-dlp
Section titled “--enable-dlp”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.
sudo awf --enable-dlp --allow-domains github.com \ -- python my_script.py--enable-api-proxy
Section titled “--enable-api-proxy”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.
# Enable with keys from environmentexport OPENAI_API_KEY="sk-..."export ANTHROPIC_API_KEY="sk-ant-..."sudo -E awf --enable-api-proxy \ --allow-domains api.openai.com,api.anthropic.com \ -- commandRequired 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 |
--copilot-api-target <host>
Section titled “--copilot-api-target <host>”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
sudo -E awf --enable-api-proxy \ --copilot-api-target api.github.mycompany.com \ --allow-domains api.github.mycompany.com \ -- command--openai-api-target <host>
Section titled “--openai-api-target <host>”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
sudo -E awf --enable-api-proxy \ --openai-api-target llm-router.internal.example.com \ --allow-domains llm-router.internal.example.com \ -- command--openai-base-url-env <name>
Section titled “--openai-base-url-env <name>”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
sudo -E awf --enable-api-proxy \ --openai-base-url-env CODEX_LB_BASE_URL \ -- codex exec "..."--openai-api-base-path <path>
Section titled “--openai-api-base-path <path>”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
# Databricks serving endpointsudo -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--api-proxy-ca-cert <path>
Section titled “--api-proxy-ca-cert <path>”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
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--anthropic-api-target <host>
Section titled “--anthropic-api-target <host>”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
sudo -E awf --enable-api-proxy \ --anthropic-api-target llm-router.internal.example.com \ --allow-domains llm-router.internal.example.com \ -- command--anthropic-api-base-path <path>
Section titled “--anthropic-api-base-path <path>”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
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--gemini-api-target <host>
Section titled “--gemini-api-target <host>”Target hostname for Gemini API requests. Useful for private gateways or compatible Gemini endpoints.
- Default:
generativelanguage.googleapis.com - Requires:
--enable-api-proxy
sudo -E awf --enable-api-proxy \ --gemini-api-target ai-gateway.internal.example.com \ --allow-domains ai-gateway.internal.example.com \ -- command--gemini-api-base-path <path>
Section titled “--gemini-api-base-path <path>”Base path prefix prepended to Gemini API requests.
- Default: none
- Requires:
--enable-api-proxy
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--rate-limit-rpm <n>
Section titled “--rate-limit-rpm <n>”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
sudo -E awf --enable-api-proxy \ --rate-limit-rpm 100 \ --allow-domains api.openai.com \ -- command--rate-limit-rph <n>
Section titled “--rate-limit-rph <n>”Maximum number of requests per hour per provider.
- Default:
10000(when rate limiting is enabled) - Requires:
--enable-api-proxy
sudo -E awf --enable-api-proxy \ --rate-limit-rph 5000 \ --allow-domains api.anthropic.com \ -- command--rate-limit-bytes-pm <n>
Section titled “--rate-limit-bytes-pm <n>”Maximum request bytes per minute per provider.
- Default:
52428800(~50 MB, when rate limiting is enabled) - Requires:
--enable-api-proxy
sudo -E awf --enable-api-proxy \ --rate-limit-bytes-pm 10485760 \ --allow-domains api.openai.com \ -- command--no-rate-limit
Section titled “--no-rate-limit”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
sudo -E awf --enable-api-proxy --no-rate-limit \ --allow-domains api.anthropic.com \ -- command--enable-token-steering
Section titled “--enable-token-steering”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
sudo -E awf --enable-api-proxy \ --enable-token-steering \ --allow-domains api.anthropic.com \ -- command--difc-proxy-host <host:port>
Section titled “--difc-proxy-host <host:port>”Connect to an external DIFC proxy (mcpg) and enable the CLI proxy sidecar for gh command routing.
sudo awf --difc-proxy-host 127.0.0.1:5555 \ --allow-domains github.com \ -- gh repo view github/gh-aw-firewall--difc-proxy-ca-cert <path>
Section titled “--difc-proxy-ca-cert <path>”Path to a CA certificate written by the external DIFC proxy. Recommended when using --difc-proxy-host over TLS.
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--diagnostic-logs
Section titled “--diagnostic-logs”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).
Implicit Behaviors
Section titled “Implicit Behaviors”Enterprise domain auto-detection
Section titled “Enterprise domain auto-detection”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.
GitHub Enterprise Cloud (GHEC)
Section titled “GitHub Enterprise Cloud (GHEC)”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.
# 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.comsudo awf --allow-domains github.com -- copilot-agentGitHub Enterprise Server (GHES)
Section titled “GitHub Enterprise Server (GHES)”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 |
# 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.comsudo awf --allow-domains github.com -- copilot-agentEnvironment Variables
Section titled “Environment Variables”AWF reads several environment variables that influence its behavior. These are grouped by purpose.
Credentials (API Proxy Sidecar)
Section titled “Credentials (API Proxy Sidecar)”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 |
API Target Overrides
Section titled “API Target Overrides”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 |
Exit Codes
Section titled “Exit Codes”| Code | Description |
|---|---|
0 |
Command succeeded |
1-255 |
Command exit code or firewall error |
130 |
Interrupted by SIGINT (Ctrl+C) |
143 |
Terminated by SIGTERM |
Subcommands
Section titled “Subcommands”awf predownload
Section titled “awf predownload”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.
awf predownload [options]Options
Section titled “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 |
Examples
Section titled “Examples”# Pre-download default images (squid + agent)awf predownload
# Pre-download including the API proxy imageawf predownload --enable-api-proxy
# Pre-download including the CLI proxy imageawf predownload --difc-proxy
# Pre-download a specific versionawf predownload --image-tag v0.3.0
# Pre-download the act (GitHub Actions parity) agent imageawf predownload --agent-image act
# Use a custom registryawf predownload --image-registry ghcr.io/myorg/awf
# After pre-downloading, run without pullingsudo awf --skip-pull --allow-domains github.com -- curl https://api.github.comawf logs
Section titled “awf logs”View Squid proxy logs from current or previous runs.
awf logs [options]Options
Section titled “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) |
Output Formats
Section titled “Output Formats”| Format | Description |
|---|---|
pretty |
Colorized, human-readable output (default) |
raw |
Logs as-is without parsing |
json |
Structured JSON for scripting |
Examples
Section titled “Examples”# View recent logs with pretty formattingawf logs
# Follow logs in real-timeawf logs -f
# View logs in JSON formatawf logs --format json
# List available log sourcesawf logs --list
# Use a specific log directoryawf logs --source /tmp/squid-logs-1234567890
# Stream from running containerawf logs --source running -f
# Follow logs with PID/process trackingawf logs -f --with-pidPID Tracking
Section titled “PID Tracking”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"}awf logs stats
Section titled “awf logs stats”Show aggregated statistics from firewall logs.
awf logs stats [options]Options
Section titled “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 |
Output Formats
Section titled “Output Formats”| 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 |
Examples
Section titled “Examples”# Show stats with colorized terminal outputawf logs stats
# Get stats in JSON format for scriptingawf logs stats --format json
# Get stats in markdown formatawf logs stats --format markdown
# Use a specific log directoryawf logs stats --source /tmp/squid-logs-1234567890Example Output (Pretty)
Section titled “Example Output (Pretty)”Firewall Statistics────────────────────────────────────────
Total Requests: 150Allowed: 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 deniedawf logs summary
Section titled “awf logs summary”Generate summary report optimized for GitHub Actions step summaries.
awf logs summary [options]Options
Section titled “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 |
Examples
Section titled “Examples”# Generate markdown summary (default)awf logs summary
# Add to GitHub Actions step summaryawf logs summary >> $GITHUB_STEP_SUMMARY
# Get summary in JSON formatawf logs summary --format json
# Get summary with colorized terminal outputawf logs summary --format prettyExample Output (Markdown)
Section titled “Example Output (Markdown)”<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>awf logs audit
Section titled “awf logs audit”Show firewall audit with policy rule matching. Enriches log entries with the specific policy rule that caused each allow/deny decision.
awf logs audit [options]Options
Section titled “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 |
Examples
Section titled “Examples”# Show audit report with colorized terminal outputawf logs audit
# Show audit in JSON formatawf logs audit --format json
# Generate markdown audit reportawf logs audit --format markdown
# Filter to denied requests onlyawf logs audit --decision denied
# Filter to a specific domainawf logs audit --domain github.com
# Filter by rule IDawf logs audit --rule allow-both-plain
# Use a specific log directoryawf logs audit --source /tmp/squid-logs-1234567890Example Output (Pretty)
Section titled “Example Output (Pretty)”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-denySee Also
Section titled “See Also”- API Proxy Sidecar - Secure credential injection architecture and configuration
- Domain Filtering Guide - Allowlists, blocklists, wildcards, and protocol-specific filtering
- Playwright Testing - Using the
localhostkeyword for local development - SSL Bump Reference - HTTPS content inspection and URL filtering
- Quick Start Guide - Getting started with examples
- Usage Guide - Detailed usage patterns and examples
- Troubleshooting - Common issues and solutions
- Security Architecture - How the firewall works internally