Skip to content

Compiler support for AWF --network-isolation (Docker-topology egress for ARC/DinD) #41072

Description

@lpcox

Summary

AWF (@github/awf) has merged an opt-in --network-isolation egress model (github/gh-aw-firewall#5237) that enforces egress via Docker network topology — an --internal awf-net network with a dual-homed Squid sidecar — instead of host iptables / NET_ADMIN. The primary motivation is ARC (Actions Runner Controller) Kubernetes runners with a DinD sidecar, where NET_ADMIN and host-iptables are unavailable.

The gh-aw compiler now needs a companion change so generated workflows can opt into this mode. This is the §8.2 work item from the AWF design note (docs/network-isolation-design.md).

AWF-side surface already shipped (what the compiler must target)

  • CLI flag: --network-isolation.
  • Config-file equivalents (consumed via awf --config): network.isolation: true and network.topologyAttach: [<container names>] (added to the canonical awf-config.schema.json; topologyAttach requires isolation: true).
  • Repeatable CLI flag --topology-attach <name> — passes gateway/DIFC container names so AWF runs docker network connect awf-net <container> after startup.
  • Deterministic internal network name is awf-net.
  • Fail-stop preflight: AWF aborts with a clear "platform unsupported" message if no Docker daemon is reachable (specializes for the ARC k8s-native fingerprint). Network-isolation is only supported when a DinD/Docker daemon is present.

Required compiler changes (§8.2)

Per docs/network-isolation-design.md §8.2:

  1. Launch mcpg gateway mode as a bridge container with a static awf-net-compatible IP (not --network host); drop the --add-host host.docker.internal:127.0.0.1 loopback trick.
  2. Launch DIFC / cli-proxy mode as a bridge container with -p 127.0.0.1:18443:18443 (published for host pre-steps) instead of --network host.
  3. Emit the network-attach handshake: pass the gateway/DIFC container names to AWF via --topology-attach <name> (or network.topologyAttach), and point the agent's MCP gateway address + cli-proxy DIFC target at the internal awf-net addresses.
  4. When network-isolation is set, stop passing --enable-host-access --allow-host-ports … / --difc-proxy-host host.docker.internal:…; pass the internal equivalents instead.
  5. Under ARC/DinD, point pre-step GH_HOST at the dind-reachable DIFC address rather than localhost.

Note: there are two mcpg instances — gateway mode (agent traffic) and proxy mode (launched early in a pre-agent step so pre-step gh CLI commands are captured). Both need the bridge/internal-address treatment under isolation.

Concrete touch points in this repo (pkg/workflow/)

  • AWF flag emissionawf_helpers.go:616-652: --enable-host-access (616-619), --allow-host-ports 80,443,<mcpPort> (621-635), --difc-proxy-host host.docker.internal:18443 + --difc-proxy-ca-cert (644-648). These are the flags §8.2 changes under isolation.
  • AWF config structawf_config.go:154-257 (AWFConfigFile / AWFNetworkConfig). A new isolation toggle / topologyAttach would serialize here. Config JSON assembled at awf_config.go:322-480.
  • MCP gateway container launchmcp_setup_generator.go:741-786: docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 … (762-763). Gateway address selection at mcp_setup_generator.go:631-652.
  • DIFC / cli-proxy launchcompiler_difc_proxy.go:468-526 (buildStartCliProxyStepYAML) + start_cli_proxy.sh; AWF→proxy wiring via host.docker.internal:18443 (compiler_difc_proxy.go:468-470, awf_helpers.go:644-648); proxy env routes GitHub API at compiler_difc_proxy.go:311-320.
  • Frontmatter → compiler threading — schema pkg/parser/schemas/main_workflow_schema.json; compiler structs pkg/workflow/compiler_types.go:453-541 (WorkflowData), engine.go:28-80, sandbox.go:34-62.
  • Embedded AWF config schema syncpkg/workflow/schemas/awf-config.schema.json (//go:embed at awf_config.go:74-75) must gain the new network.isolation / network.topologyAttach fields. Drift procedure: specs/awf-config-sources-spec.md:92-130.
  • Golden fixturespkg/workflow/testdata/wasm_golden/…; regenerate with make update-wasm-golden (i.e. go test -v -run='^TestWasmGolden_' ./pkg/workflow -update).

Open design questions

  • Enablement surface: explicit user-facing frontmatter toggle (e.g. engine.firewall.network-isolation) vs. auto-enable under a detected ARC/DinD condition. (AWF keeps it opt-in/experimental today.)
  • Handshake mechanism: --topology-attach <name> flags vs. network.topologyAttach config array.
  • Static IP assignment for the gateway/DIFC bridge containers within awf-net, vs. attaching by container name and relying on Docker DNS.

Out of scope (§8.3, tracked separately)

  • ARC containerMode: kubernetes (no Docker daemon) — unsupported by policy; AWF fails stop.
  • Forcing child MCP-server egress through Squid — deprioritized.

References

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions