Skip to content

feat: Add docker-sbx runtime support to compiler #44978

Description

@lpcox

Summary

Add docker-sbx as a new sandbox.agent.runtime option in the gh-aw compiler, alongside the existing gvisor runtime (merged in #44796). This runtime runs the agent inside a Docker sbx microVM with hypervisor-level isolation (KVM), while infrastructure containers (Squid proxy, api-proxy, MCP gateway) remain in Docker Compose on the host.

The AWF (gh-aw-firewall) side is implemented in github/gh-aw-firewall#6101. This issue covers the compiler changes needed to generate the correct lock.yml for docker-sbx workflows.

Proposed Frontmatter

sandbox:
  agent:
    id: awf
    runtime: docker-sbx
    sudo: true   # required — install step uses sudo

This follows the same pattern as runtime: gvisor (#44796). When sandbox.agent.runtime: docker-sbx is set, the compiler should generate the following additional steps and configuration changes in the lock.yml.

Required Compiler Changes

1. Early Fail-Fast Checks (new steps)

Generate steps that run before sbx installation:

  • KVM availability: Check lsmod | grep kvm and /dev/kvm writability. Fail immediately with a clear error if KVM is not available (runner must support nested virtualization).
  • Docker secrets: Verify secrets.DOCKER_PAT and secrets.DOCKER_USERNAME are non-empty. Fail with actionable error message if either is missing.

2. sbx Installation Step (analogous to generateGVisorInstallStep)

Like generateGVisorInstallStep(), add a generateDockerSbxInstallStep():

# Add Docker apt repo (REPO_ONLY=1 skips installing Docker Engine)
curl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh
sudo apt-get install -y docker-sbx
sbx version

# Fix KVM permissions for runner user
sudo chmod 666 /dev/kvm

3. sbx Authentication & Daemon Startup

# Start daemon
nohup sbx daemon start > /tmp/sbx-daemon.log 2>&1 &
# Wait for running state (poll up to 10s)

# Authenticate with Docker Hub
printf '%s' "$DOCKER_PAT_VAL" | docker login --username "$DOCKER_USERNAME_VAL" --password-stdin
printf '%s' "$DOCKER_PAT_VAL" | sbx login --username "$DOCKER_USERNAME_VAL" --password-stdin

# Reset policy and re-initialize (required for mount policy)
sbx daemon stop || true
sbx policy reset --force || true
sbx policy init allow-all
# Restart daemon + re-authenticate

# Pre-pull template image
docker pull docker/sandbox-templates:shell-docker

4. sbx Pre-Flight Smoke Test

After install and auth, verify the sbx stack works end-to-end before committing to the expensive MCP gateway and AWF container setup. This catches daemon failures, KVM issues, or image pull problems early:

# Create a throwaway sandbox, exec a command, then clean up
yes | sbx create shell --name test-sandbox-direct "$GITHUB_WORKSPACE"
sbx exec test-sandbox-direct uname -a
sbx stop test-sandbox-direct
sbx rm --force test-sandbox-direct
echo "✅ sbx ready"

If this fails, the step should error with a clear message indicating the sbx environment is not functional.

5. MCP Gateway Routing for microVM

The sbx microVM cannot resolve Docker container names. The MCP gateway must be accessible via host.docker.internal:

  • Bind MCP gateway to 0.0.0.0 (not 127.0.0.1) so it is reachable from non-loopback addresses
  • Set MCP_GATEWAY_HOST_DOMAIN=host.docker.internal
  • Use host.docker.internal as gateway.domain in mcp-config.json
  • Use host.docker.internal as MCP_GATEWAY_DOMAIN in the "Mount MCP servers as CLIs" step (so generated CLI wrapper scripts point to the correct URL from inside the microVM)

6. AWF Config Generation

When docker-sbx runtime is selected:

  • Pass --container-runtime sbx to the awf CLI invocation
  • Add host.docker.internal to network.allowDomains
  • Set network.isolation: true (disables host iptables — enforcement is purely via Docker network topology, regardless of sudo: true)
  • Keep topologyAttach: ["awmg-mcpg"] (AWF connects the MCP gateway container to awf-net for infrastructure routing)

7. Credential Exclusion (Security-Critical)

The agent must never have access to real authentication tokens. Add these flags to the AWF invocation:

--exclude-env COPILOT_GITHUB_TOKEN
--exclude-env GITHUB_MCP_SERVER_TOKEN
--exclude-env MCP_GATEWAY_API_KEY

The api-proxy sidecar handles credential injection transparently. The agent receives:

  • COPILOT_API_URL=http://host.docker.internal:10002 (api-proxy)
  • COPILOT_PROVIDER_BASE_URL=http://host.docker.internal:10002
  • A dummy BYOK key (never the real token)

8. Compile-Time Validation

Reject incompatible combinations at compile time:

Combination Error
runtime: docker-sbx + runner.topology: arc-dind sbx requires KVM; ARC DinD runners typically lack nested virt
runtime: docker-sbx + sudo: false (default) Install step requires root; must set sudo: true
runtime: docker-sbx without DOCKER_PAT/DOCKER_USERNAME secrets configured sbx requires Docker Hub authentication

Like gVisor, sudo: true's deprecation warning/error should be suppressed when runtime: docker-sbx is set — sbx fundamentally requires root so the warning would be misleading.

Important: Despite requiring sudo: true, the network topology must always use network.isolation: true (no host iptables). The sudo is only for the install steps, not for network enforcement.

9. Schema & Documentation

  • Add docker-sbx to the sandbox.agent.runtime enum in main_workflow_schema.json (alongside gvisor)
  • Add AgentRuntimeDockerSbx AgentRuntime = "docker-sbx" constant in sandbox.go
  • Add isDockerSbxRuntime() helper in firewall.go
  • Document required secrets: DOCKER_PAT, DOCKER_USERNAME
  • Document hardware requirement: KVM-capable runner (e.g., GitHub-hosted ubuntu-latest 4-core+)

Architecture Reference

Host Runner
├── Docker Compose (awf-net, internal + awf-ext, bridge)
│   ├── awf-squid (172.30.0.10) — domain ACL filtering
│   ├── awf-api-proxy (172.30.0.30) — credential injection, on awf-ext
│   └── awmg-mcpg (bridge, published 0.0.0.0:8080) — MCP gateway
│
└── Docker sbx microVM (KVM-isolated)
    ├── eth0 gateway: 172.17.0.0
    ├── host.docker.internal → 172.17.0.1 (docker0 bridge)
    ├── Squid: via 172.17.0.0:3128 (port-published)
    ├── Api-proxy: via host.docker.internal:10000-10004 (docker0 bridge → awf-ext)
    ├── MCP gateway: via host.docker.internal:8080 (port-published)
    └── Direct outbound: BLOCKED (proxy-only egress)

Key Differences from gVisor

Aspect gVisor docker-sbx
Isolation Userspace kernel (OCI runtime) Hardware VM (KVM hypervisor)
Agent lifecycle Docker Compose service External sbx CLI
Docker runtime field runsc N/A (not OCI)
Sudo required Yes (install step) Yes (install step)
Network isolation network.isolation: true network.isolation: true (always, regardless of sudo)
Static DNS needed Yes (gVisor netstack quirk) No (sbx manages DNS)
Agent in compose Yes No (omitted from docker-compose.yml)
Extra secrets None DOCKER_PAT, DOCKER_USERNAME
Pre-pull required No Yes (docker/sandbox-templates:shell-docker)
Pre-flight test No Yes (create → exec → rm throwaway sandbox)

Acceptance Criteria

  • sandbox.agent.runtime: docker-sbx compiles to a valid lock.yml
  • Lock.yml includes KVM + secrets fail-fast checks
  • Lock.yml includes sbx install, auth, and daemon startup
  • Lock.yml includes pre-flight smoke test (create → exec → rm)
  • MCP gateway bound to 0.0.0.0 and CLI wrappers use host.docker.internal
  • AWF invoked with --container-runtime sbx and credential exclusion flags
  • Agent cannot access real auth tokens (COPILOT_GITHUB_TOKEN, MCP_GATEWAY_API_KEY, GITHUB_MCP_SERVER_TOKEN)
  • host.docker.internal in allowDomains
  • network.isolation: true always set (even with sudo: true)
  • Compile-time validation rejects incompatible combinations
  • sudo: true required (error if omitted), deprecation warning suppressed
  • Schema updated (main_workflow_schema.json)
  • Documentation updated with new runtime option and requirements

Related

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

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