This document defines the canonical configuration model for AWF (awf) and is intended for:
awfCLI runtime loading (--config)- tooling that compiles workflows to AWF invocations (including
gh-aw) - IDE/static validation via JSON Schema
The machine-readable schema is published at:
docs/awf-config.schema.json— live schema (always reflects latestmain)- GitHub release asset
awf-config.schema.json— versioned, stable URL per release (e.g.https://github.com/github/gh-aw-firewall/releases/download/v0.23.1/awf-config.schema.json)
The normative keywords in this document are to be interpreted as described in RFC 2119.
An AWF config document is conforming when:
- It is valid JSON or YAML.
- Its data model satisfies
docs/awf-config.schema.json. - Unknown properties are not present (closed-world schema).
- The user invokes
awf --config <path|-> -- <command>. - If
<path>is-, AWF reads configuration bytes from stdin. - If
<path>ends with.json, AWF parses as JSON. - If
<path>ends with.yamlor.yml, AWF parses as YAML. - Otherwise, AWF attempts JSON parse first, then YAML parse.
- AWF validates the parsed document and fails fast on validation errors.
- AWF maps config fields to CLI option semantics.
- CLI options MUST take precedence over config file values.
The effective configuration order is:
- AWF internal defaults
- Config file (
--config) - Explicit CLI flags
This precedence model allows reusable checked-in configs with environment-specific CLI overrides.
The root object MAY contain:
$schemanetworkapiProxysecuritycontainerenvironmentloggingrateLimiting
Section semantics and constraints are defined by docs/awf-config.schema.json.
Tools generating AWF invocations (such as gh-aw) SHOULD use this mapping:
network.allowDomains[]→--allow-domains <csv>network.blockDomains[]→--block-domains <csv>network.dnsServers[]→--dns-servers <csv>network.upstreamProxy→--upstream-proxyapiProxy.enabled→--enable-api-proxyapiProxy.enableOpenCode→--enable-opencodeapiProxy.anthropicAutoCache→--anthropic-auto-cacheapiProxy.anthropicCacheTailTtl→--anthropic-cache-tail-ttlapiProxy.maxEffectiveTokens→ config-only (maps to API proxy effective-token guard)apiProxy.modelMultipliers→ config-only (maps to API proxy effective-token multipliers)apiProxy.models→ config-only (maps to API proxy model alias rewriting)apiProxy.targets.<provider>.host→--<provider>-api-targetapiProxy.targets.openai.basePath→--openai-api-base-pathapiProxy.targets.anthropic.basePath→--anthropic-api-base-pathapiProxy.targets.gemini.basePath→--gemini-api-base-pathsecurity.sslBump→--ssl-bumpsecurity.enableDlp→--enable-dlpsecurity.enableHostAccess→--enable-host-accesssecurity.allowHostPorts→--allow-host-portssecurity.allowHostServicePorts→--allow-host-service-portssecurity.difcProxy.host→--difc-proxy-hostsecurity.difcProxy.caCert→--difc-proxy-ca-certcontainer.memoryLimit→--memory-limitcontainer.agentTimeout→--agent-timeoutcontainer.enableDind→--enable-dindcontainer.workDir→--work-dircontainer.containerWorkDir→--container-workdircontainer.imageRegistry→--image-registrycontainer.imageTag→--image-tagcontainer.skipPull→--skip-pullcontainer.buildLocal→--build-localcontainer.agentImage→--agent-imagecontainer.tty→--ttycontainer.dockerHost→--docker-hostenvironment.envFile→--env-fileenvironment.envAll→--env-allenvironment.excludeEnv[]→ repeated--exclude-env- (CLI-only)
-e, --env <KEY=VALUE>— no config-file equivalent by design logging.logLevel→--log-levellogging.diagnosticLogs→--diagnostic-logslogging.auditDir→--audit-dirlogging.proxyLogsDir→--proxy-logs-dirlogging.sessionStateDir→--session-state-dirrateLimiting.enabled: false→--no-rate-limitrateLimiting.requestsPerMinute→--rate-limit-rpmrateLimiting.requestsPerHour→--rate-limit-rphrateLimiting.bytesPerMinute→--rate-limit-bytes-pm
AWF MUST support --config - for programmatic/pipeline scenarios.
On parse or validation failure, AWF MUST:
- exit non-zero
- print an error describing location and reason
- avoid partial execution
The agent container's environment is constructed by merging variables from multiple sources. This section defines the normative merge order and exclusion rules.
For usage guidance and examples, see docs/environment.md.
- AWF-reserved variables — proxy routing, DNS, container paths (always set)
--env-all— inherited host environment (when enabled)--env-file— variables read from a file-e / --env— explicit CLI key-value pairs
A value set at a higher level MUST override any value from a lower level.
AWF MUST set the following variables in the agent container regardless of user
configuration. These MUST NOT be overridden by --env-all or --env-file:
| Variable | Value | Purpose |
|---|---|---|
HTTP_PROXY |
http://<squid-ip>:3128 |
Squid forward proxy for HTTP |
HTTPS_PROXY |
http://<squid-ip>:3128 |
Squid forward proxy for HTTPS |
https_proxy |
http://<squid-ip>:3128 |
Lowercase alias for tools that only check lowercase (Yarn 4, undici) |
NO_PROXY |
localhost,127.0.0.1,::1,... |
Loopback and container IPs bypassing Squid |
SQUID_PROXY_HOST |
squid-proxy |
Proxy hostname for tools needing host separately |
SQUID_PROXY_PORT |
3128 |
Proxy port |
PATH |
Container default | MUST use the container's PATH, not the host's |
HOME |
Host user's home | Derived from sudo-aware detection |
Note: Lowercase http_proxy is intentionally NOT set. Some curl builds on
Ubuntu 22.04 ignore uppercase HTTP_PROXY for HTTP URLs (httpoxy mitigation),
causing HTTP traffic to fall through to iptables DNAT — the intended behavior.
The following variables MUST be excluded from --env-all and --env-file
passthrough. They are never inherited from the host:
- System variables:
PATH,PWD,OLDPWD,SHLVL,_,SUDO_COMMAND,SUDO_USER,SUDO_UID,SUDO_GID - Proxy variables:
HTTP_PROXY,HTTPS_PROXY,http_proxy,https_proxy,NO_PROXY,no_proxy,ALL_PROXY,all_proxy,FTP_PROXY,ftp_proxy - Actions artifact tokens:
ACTIONS_RUNTIME_TOKEN,ACTIONS_RESULTS_URL - AWF internal controls:
AWF_PREFLIGHT_BINARY,AWF_GEMINI_ENABLED
Host proxy variables are read for upstream proxy auto-detection but are excluded from the agent's environment. AWF sets its own proxy variables pointing to Squid.
When --env-all is NOT active, AWF SHOULD forward a selective set of
commonly needed host variables:
- GitHub auth:
GITHUB_TOKEN,GH_TOKEN,GITHUB_PERSONAL_ACCESS_TOKEN - GitHub enterprise:
GITHUB_SERVER_URL,GITHUB_API_URL - Actions OIDC:
ACTIONS_ID_TOKEN_REQUEST_URL,ACTIONS_ID_TOKEN_REQUEST_TOKEN - Docker client:
DOCKER_HOST,DOCKER_TLS,DOCKER_TLS_VERIFY,DOCKER_CERT_PATH,DOCKER_CONFIG,DOCKER_CONTEXT,DOCKER_API_VERSION,DOCKER_DEFAULT_PLATFORM - User environment:
USER,XDG_CONFIG_HOME
When --env-all IS active, all host variables not in the excluded set
(§8.3) are forwarded, subject to credential isolation rules (§9).
Variables passed via -e / --env MUST override all other sources, including
AWF-reserved variables. This is the only mechanism that can override proxy
routing variables.
There is no config-file equivalent for -e / --env by design. Individual
environment variable injection is a runtime concern, not a static configuration
concern.
AWF implements defense-in-depth credential isolation for LLM API keys. The
behavior depends on whether the API proxy sidecar is enabled (apiProxy.enabled).
For architectural details and diagrams, see docs/authentication-architecture.md.
The following environment variables are recognized as source credentials (real API keys read from the host environment):
| Variable | Provider |
|---|---|
OPENAI_API_KEY |
OpenAI |
ANTHROPIC_API_KEY |
Anthropic (Claude) |
COPILOT_GITHUB_TOKEN |
GitHub Copilot |
COPILOT_API_KEY |
GitHub Copilot (BYOK) |
GEMINI_API_KEY |
Google Gemini |
Secondary aliases recognized: OPENAI_KEY, CODEX_API_KEY, CLAUDE_API_KEY,
COPILOT_PROVIDER_API_KEY.
When apiProxy.enabled is true:
-
Source credentials MUST NOT be exposed to the agent container's environment. They are passed exclusively to the API proxy sidecar.
-
--env-allMUST NOT reintroduce excluded credentials into the agent environment when API proxy isolation is active. -
AWF MAY inject placeholder values into the agent container for tool compatibility (e.g.,
OPENAI_API_KEY=sk-placeholder-for-api-proxy). These are not secrets. -
AWF MUST inject proxy-routing variables so agent tools reach the sidecar instead of upstream APIs:
Agent variable Value Purpose OPENAI_BASE_URLhttp://172.30.0.30:10000Routes OpenAI calls to sidecar ANTHROPIC_BASE_URLhttp://172.30.0.30:10001Routes Anthropic calls to sidecar COPILOT_API_URLhttp://172.30.0.30:10002Routes Copilot calls to sidecar GOOGLE_GEMINI_BASE_URLhttp://172.30.0.30:10003Routes Gemini calls to sidecar GEMINI_API_BASE_URLhttp://172.30.0.30:10003Gemini alias for compatibility -
The API proxy sidecar injects the real credentials into upstream requests. Sidecar ports: 10000 (OpenAI), 10001 (Anthropic), 10002 (Copilot), 10003 (Gemini), 10004 (OpenCode).
When apiProxy.enabled is false (default):
- Source credentials present in the host environment SHOULD be forwarded directly to the agent container.
- No proxy-routing variables or placeholders are injected.
Real credentials forwarded to the agent (whether source credentials in
non-proxy mode or GITHUB_TOKEN / GH_TOKEN) MUST be protected by the
one-shot-token mechanism. Protected tokens are cached on first access and
unset from /proc/self/environ to prevent environment variable inspection.
The default protected token list is:
COPILOT_GITHUB_TOKEN, GITHUB_TOKEN, GH_TOKEN, GITHUB_API_TOKEN,
GITHUB_PAT, GH_ACCESS_TOKEN, OPENAI_API_KEY, OPENAI_KEY,
ANTHROPIC_API_KEY, CLAUDE_API_KEY, CODEX_API_KEY, COPILOT_API_KEY,
COPILOT_PROVIDER_API_KEY
Placeholder compatibility values (§9.2 item 3) are NOT secrets and are not subject to one-shot protection.
When security.difcProxy.host is set, GITHUB_TOKEN and GH_TOKEN MUST be
excluded from the agent environment. Tokens are held by the external DIFC proxy.