Problem
The gh-aw compiler currently generates AWF invocations using command-line flags:
awf --allow-domains github.com api.github.com \
--enable-api-proxy \
--dns-servers 8.8.8.8,8.8.4.4 \
--image-tag v0.25.29 \
--agent-timeout 300 \
...
-- "claude ..."
As AWF gains more configuration surface (model policies, rate limits, api-proxy targets, container settings), this approach has scaling problems:
- Shell escaping — Complex values (JSON objects, multi-line strings) are fragile in shell argv
- Readability — Long flag lists in lock files are hard to audit
- Composability — No clean way to layer org-level defaults with workflow-level overrides
- Validation — Flags are validated only at runtime; config files can be schema-validated at compile time
Proposed Solution
AWF already supports --config <path|-> which loads a JSON/YAML config file (gh-aw-firewall src/config-file.ts). The compiler should generate a config file and invoke AWF with it:
awf --config .awf-config.json -- "claude ..."
Where .awf-config.json contains the structured configuration:
{
"$schema": "https://github.com/github/gh-aw-firewall/schemas/awf-config.v1.json",
"network": {
"allowDomains": ["github.com", "api.github.com", "*.actions.githubusercontent.com"],
"dnsServers": ["8.8.8.8", "8.8.4.4"]
},
"apiProxy": {
"enabled": true,
"targets": {
"openai": { "host": "api.openai.com" },
"anthropic": { "host": "api.anthropic.com" },
"copilot": { "host": "api.githubcopilot.com" }
}
},
"container": {
"imageTag": "v0.25.29",
"agentTimeout": 300,
"buildLocal": false
},
"modelPolicy": {
"model": { "id": "claude-sonnet-4-20250514", "provider": "anthropic" },
"fallback": [{ "strategy": "auto" }],
"onUnavailable": "fail"
}
}
Benefits
| Aspect |
CLI flags (current) |
Config file (proposed) |
| Complex values |
Shell escaping issues |
Native JSON types |
| Auditability |
Long one-liner |
Structured, diffable |
| Schema validation |
Runtime only |
Compile-time + IDE support |
| Composability |
Flag precedence only |
File merging + overlays |
| New features |
New flag per feature |
Add to schema, no argv changes |
| Model policy |
Not expressible |
First-class object (#2309) |
Implementation Plan
Phase 1: Compiler generates config file
- Compiler emits
.awf-config.json alongside the lock file (or inline via --config - on stdin)
- Lock file
run: step changes from flag soup to awf --config .awf-config.json -- "..."
- Backwards compatible: AWF already supports
--config; CLI flags still override for user ad-hoc runs
Phase 2: Schema validation at compile time
- Publish JSON Schema in gh-aw-firewall (
schemas/awf-config.v1.json)
gh aw compile --validate validates the generated config against the schema
- IDE support via
$schema field for autocomplete in editors
Phase 3: Composable config layers
- Org-level defaults (
.github/awf-config.json)
- Workflow-level overrides (frontmatter → config)
- CLI flags as final override layer
- Merge semantics: deep merge with arrays replaced (not appended)
AWF Config File Support (already implemented)
The firewall already supports config files via --config <path|->:
- Parses JSON or YAML
- Validates against known schema sections:
network, apiProxy, container
- Maps config keys to CLI option equivalents
- CLI flags take precedence over file values
Key source files:
Related
- gh-aw-firewall#2309 — Model-selection policy schema (new config section)
- gh-aw#29191 — Model fallback feature request
- AWF
--config docs: awf --help → --config <path|-> Load configuration from JSON/YAML file (use - for stdin)
Problem
The gh-aw compiler currently generates AWF invocations using command-line flags:
awf --allow-domains github.com api.github.com \ --enable-api-proxy \ --dns-servers 8.8.8.8,8.8.4.4 \ --image-tag v0.25.29 \ --agent-timeout 300 \ ... -- "claude ..."As AWF gains more configuration surface (model policies, rate limits, api-proxy targets, container settings), this approach has scaling problems:
Proposed Solution
AWF already supports
--config <path|->which loads a JSON/YAML config file (gh-aw-firewallsrc/config-file.ts). The compiler should generate a config file and invoke AWF with it:awf --config .awf-config.json -- "claude ..."Where
.awf-config.jsoncontains the structured configuration:{ "$schema": "https://github.com/github/gh-aw-firewall/schemas/awf-config.v1.json", "network": { "allowDomains": ["github.com", "api.github.com", "*.actions.githubusercontent.com"], "dnsServers": ["8.8.8.8", "8.8.4.4"] }, "apiProxy": { "enabled": true, "targets": { "openai": { "host": "api.openai.com" }, "anthropic": { "host": "api.anthropic.com" }, "copilot": { "host": "api.githubcopilot.com" } } }, "container": { "imageTag": "v0.25.29", "agentTimeout": 300, "buildLocal": false }, "modelPolicy": { "model": { "id": "claude-sonnet-4-20250514", "provider": "anthropic" }, "fallback": [{ "strategy": "auto" }], "onUnavailable": "fail" } }Benefits
Implementation Plan
Phase 1: Compiler generates config file
.awf-config.jsonalongside the lock file (or inline via--config -on stdin)run:step changes from flag soup toawf --config .awf-config.json -- "..."--config; CLI flags still override for user ad-hoc runsPhase 2: Schema validation at compile time
schemas/awf-config.v1.json)gh aw compile --validatevalidates the generated config against the schema$schemafield for autocomplete in editorsPhase 3: Composable config layers
.github/awf-config.json)AWF Config File Support (already implemented)
The firewall already supports config files via
--config <path|->:network,apiProxy,containerKey source files:
src/config-file.ts— loader, validator, mappersrc/config-file.test.ts— validation testsRelated
--configdocs:awf --help→--config <path|-> Load configuration from JSON/YAML file (use - for stdin)