# Pass specific variables
awf -e MY_API_KEY=secret 'command'
# Pass multiple variables
awf -e FOO=1 -e BAR=2 'command'
# Pass all host variables (development only)
awf --env-all 'command'
# Read variables from a file
awf --env-file /tmp/runtime-paths.env 'command'
# Combine file and explicit overrides (--env takes precedence over --env-file)
awf --env-file /tmp/runtime-paths.env -e MY_VAR=override 'command'When using sudo -E, these host variables are automatically passed: GITHUB_TOKEN, GH_TOKEN, GITHUB_PERSONAL_ACCESS_TOKEN, USER, TERM, HOME, XDG_CONFIG_HOME.
The following are always set/overridden: PATH (container values).
Variables from --env flags override everything else.
Proxy variables set automatically: HTTP_PROXY, HTTPS_PROXY, and https_proxy are always set to point to the Squid proxy (http://172.30.0.10:3128). Note that lowercase http_proxy is intentionally not set — some curl builds on Ubuntu 22.04 ignore uppercase HTTP_PROXY for HTTP URLs (httpoxy mitigation), so HTTP traffic falls through to iptables DNAT interception instead. iptables DNAT serves as a defense-in-depth fallback for both HTTP and HTTPS.
Using --env-all passes all host environment variables to the container, which creates security risks:
- Credential Exposure: All variables (API keys, tokens, passwords) are written to
/tmp/awf-<timestamp>/docker-compose.ymlin plaintext - Log Leakage: Sharing logs or debug output exposes sensitive credentials
- Unnecessary Access: Extra variables increase attack surface (violates least privilege)
- Accidental Sharing: Easy to forget what's in your environment when sharing commands
Excluded variables (even with --env-all): PATH, PWD, OLDPWD, SHLVL, _, SUDO_*
Proxy variables: HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy, NO_PROXY, no_proxy, ALL_PROXY, and FTP_PROXY (all case variants) from the host are excluded from container passthrough when using --env-all. The firewall sets its own proxy variables pointing to Squid inside the container. However, host proxy variables are read for upstream proxy auto-detection — if the host has https_proxy/http_proxy set, AWF configures Squid to chain outbound traffic through that corporate proxy (see Upstream Proxy Support).
--env-file <path> reads environment variables from a file and injects them into the agent container. This is useful when variables are written to a file rather than exported into the current shell (e.g., step outputs from earlier GitHub Actions steps).
File format:
- One
KEY=VALUEpair per line - Lines starting with
#are comments and are ignored - Blank lines are ignored
- Values are taken literally (no quote stripping, no variable expansion)
Precedence (lowest → highest):
- Built-in framework variables (proxy, DNS, etc.)
--env-allhost variables--env-filevariables--env/-eexplicit variables (highest priority)
Excluded variables in --env-file (same list as --env-all): PATH, PWD, HOME, SUDO_*, etc.
Example use case — Safe Outputs MCP:
# Step output written to a file by the compiler
echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=/tmp/config.json" >> /tmp/runtime-paths.env
# AWF picks it up via --env-file
awf --env-file /tmp/runtime-paths.env --allow-domains github.com -- agent-command✅ Use --env for specific variables:
sudo awf --allow-domains github.com -e MY_API_KEY="$MY_API_KEY" 'command'✅ Use sudo -E for auth tokens:
sudo -E awf --allow-domains github.com 'copilot --prompt "..."'--env-all only in trusted local development (never in production/CI/CD)
❌ Avoid --env-all when:
- Sharing logs or configs
- Working with untrusted code
- In production/CI environments
When COPILOT_GITHUB_TOKEN is set in the host environment, AWF injects it into the agent container so the Copilot CLI can authenticate against the GitHub Copilot API.
Copilot CLI 1.0.21 introduced a startup model validation step: when COPILOT_MODEL is set, the CLI calls GET /models before executing any task. This endpoint does not accept classic PATs (ghp_* tokens), causing the agent to fail at startup with exit code 1 — before any useful work begins.
Affected combination:
COPILOT_GITHUB_TOKENis a classic PAT (prefixed withghp_)COPILOT_MODELis set in the agent environment (e.g., via--env COPILOT_MODEL=...,--env-file, or--env-all)
Unaffected: Workflows that do not set COPILOT_MODEL are not affected — the /models validation is only triggered when COPILOT_MODEL is set.
AWF detects this combination at startup and emits a [WARN] message:
⚠️ COPILOT_MODEL is set with a classic PAT (ghp_* token)
Copilot CLI 1.0.21+ validates COPILOT_MODEL via GET /models at startup.
Classic PATs are rejected by this endpoint — the agent will likely fail with exit code 1.
Use a fine-grained PAT or OAuth token, or unset COPILOT_MODEL to skip model validation.
Remediation options:
- Replace the classic PAT with a fine-grained PAT or OAuth token (these are accepted by the
/modelsendpoint). - Remove
COPILOT_MODELfrom the agent environment to skip model validation entirely.
The following environment variables are set internally by the firewall and used by container scripts:
| Variable | Description | Example |
|---|---|---|
HTTP_PROXY |
Squid forward proxy for HTTP traffic | http://172.30.0.10:3128 |
HTTPS_PROXY |
Squid forward proxy for HTTPS traffic (explicit CONNECT) | http://172.30.0.10:3128 |
https_proxy |
Lowercase alias for tools that only check lowercase (e.g., Yarn 4, undici) | http://172.30.0.10:3128 |
SQUID_PROXY_HOST |
Squid proxy hostname (for tools needing host separately) | squid-proxy |
SQUID_PROXY_PORT |
Squid proxy port | 3128 |
AWF_DNS_SERVERS |
Comma-separated list of trusted DNS servers | 8.8.8.8,8.8.4.4 |
AWF_CHROOT_ENABLED |
Whether chroot mode is enabled | true |
AWF_HOST_PATH |
Host PATH passed to chroot environment | /usr/local/bin:/usr/bin |
AWF_SESSION_STATE_DIR |
Directory for Copilot CLI session state output (equivalent to --session-state-dir) |
(unset) |
NO_PROXY |
Domains bypassing Squid (host access mode) | localhost,host.docker.internal |
Note: Most of these are set automatically based on CLI options and should not be overridden manually. AWF_SESSION_STATE_DIR is an exception — it is the environment-variable equivalent of --session-state-dir and can be set by users to configure a predictable session-state output path.
Tools installed by GitHub Actions setup-* actions (e.g., astral-sh/setup-uv, actions/setup-node, ruby/setup-ruby, actions/setup-python) are automatically available inside the AWF chroot. This works by:
setup-*actions write their tool bin directories to the$GITHUB_PATHfile.- AWF reads this file at startup and merges its entries (prepended, higher priority) into
AWF_HOST_PATH. - The chroot entrypoint exports
AWF_HOST_PATHasPATHinside the chroot, so tools likeuv,node,python3,ruby, etc. resolve correctly.
This behavior was introduced in awf v0.60.0 and is active automatically — no extra flags are required.
Fallback behavior: If GITHUB_PATH is not set (e.g., outside GitHub Actions or on self-hosted runners that don't set it), AWF uses process.env.PATH as the chroot PATH. If sudo has reset PATH before AWF runs and GITHUB_PATH is also absent, the tool's directory may be missing from the chroot PATH. In that case, invoke the tool via its absolute path or ensure GITHUB_PATH is set.
Troubleshooting: Run AWF with --log-level debug to see whether GITHUB_PATH is set and how many entries were merged:
[DEBUG] Merged 3 path(s) from $GITHUB_PATH into AWF_HOST_PATH
If you see instead:
[DEBUG] GITHUB_PATH env var is not set; skipping $GITHUB_PATH file merge …
the runner did not set GITHUB_PATH, and the tool's bin directory must already be in $PATH at AWF launch time.
The following environment variables control debugging behavior:
| Variable | Description | Default | Example |
|---|---|---|---|
AWF_ONE_SHOT_TOKEN_DEBUG |
Enable debug logging for one-shot-token library | off |
1 or true |
The one-shot-token library protects sensitive tokens (GITHUB_TOKEN, OPENAI_API_KEY, etc.) from environment variable inspection. By default, it operates silently. To troubleshoot token caching issues, enable debug logging:
# Enable debug logging
export AWF_ONE_SHOT_TOKEN_DEBUG=1
# Run AWF with sudo -E to preserve the variable
sudo -E awf --allow-domains github.com 'your-command'When enabled, the library logs:
- Token initialization messages
- Token access and caching events
- Environment cleanup confirmations
Note: Debug output goes to stderr and does not interfere with command stdout. See containers/agent/one-shot-token/README.md for complete documentation.
When a GitHub Actions workflow enables Docker-in-Docker (DinD) at the workflow scope — for example by starting a docker:dind service container and setting DOCKER_HOST: tcp://localhost:2375 in the runner's environment — AWF handles the conflict automatically.
AWF's container orchestration (Squid proxy, agent, iptables-init) must run on the local Docker daemon so that:
- bind mounts from the runner host filesystem work correctly,
- AWF's fixed subnet (
172.30.0.0/24) and iptables DNAT rules are created in the right network namespace, and - port binding expectations between containers are satisfied.
When DOCKER_HOST is set to a TCP address, AWF:
- Emits a warning (not an error) informing you that the local socket will be used for AWF's own containers.
- Clears
DOCKER_HOSTfor alldocker/docker composecalls it makes internally, so they target the local daemon. - Forwards the original
DOCKER_HOSTinto the agent container's environment, so Docker commands run by the agent still reach the DinD daemon.
jobs:
build:
runs-on: ubuntu-latest
services:
dind:
image: docker:dind
options: --privileged
ports:
- 2375:2375
env:
DOCKER_HOST: tcp://localhost:2375
steps:
- uses: actions/checkout@v4
- name: Run agent with AWF
run: |
# AWF warns about DOCKER_HOST but proceeds with local socket for its own containers.
# The agent can run `docker build` / `docker run` and they will reach the DinD daemon
# via the forwarded DOCKER_HOST inside the container.
awf --allow-domains registry-1.docker.io,ghcr.io -- docker build -t myapp .If your local Docker daemon is at a non-standard Unix socket path, use --docker-host:
awf --docker-host unix:///run/user/1000/docker.sock \
--allow-domains github.com \
-- agent-commandThis overrides the socket used for AWF's own operations without affecting the agent's DOCKER_HOST.
The DinD TCP address (e.g., tcp://localhost:2375) typically refers to the runner host's localhost interface. From inside the agent container, localhost resolves to the container's own loopback interface, not the host's. To make docker commands inside the agent reach the DinD daemon you need one of:
--enable-host-access— allows the agent to reachhost.docker.internaland setDOCKER_HOST=tcp://host.docker.internal:2375inside the agent.--enable-dind— mounts the local Docker socket (/var/run/docker.sock) directly into the agent container (only works when using the local daemon, not a remote DinD TCP socket).
When running on self-hosted runners behind a corporate proxy, AWF can chain Squid
through the upstream proxy using the cache_peer directive.
If the host has https_proxy/HTTPS_PROXY or http_proxy/HTTP_PROXY set, AWF
automatically configures Squid to route outbound traffic through that proxy.
no_proxy/NO_PROXY domain suffixes are honored as bypass rules (always_direct).
# Auto-detected — no flags needed when host proxy env vars are set
export https_proxy=http://proxy.corp.com:3128
export no_proxy=.internal.corp.com,localhost
awf --allow-domains github.com 'curl https://api.github.com'Use --upstream-proxy <url> to specify the proxy explicitly (overrides auto-detection):
awf --upstream-proxy http://proxy.corp.com:3128 --allow-domains github.com 'curl https://api.github.com'- HTTP proxies only — Squid
cache_peerrequires an HTTP proxy (HTTPS tunneling uses CONNECT) - No proxy credentials —
user:pass@proxyURLs are rejected; configure auth on the proxy server - No loopback —
localhost/127.0.0.1proxies are rejected (Squid is in a container) - Single proxy — If
http_proxyandhttps_proxydiffer, use--upstream-proxyto disambiguate - Domain-only bypass —
no_proxyIPs, CIDRs, and wildcards are ignored (only domain suffixes work)
Host proxy environment variables (HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy,
ALL_PROXY, NO_PROXY, etc.) are always excluded from container passthrough, even with
--env-all. AWF sets its own proxy variables pointing to Squid (172.30.0.10:3128).
Variable not accessible: Use sudo -E or pass explicitly with --env VAR="$VAR"
Variable empty: Check if it's in the excluded list or wasn't exported on host (export VAR=value)