Skip to content

feat: add gVisor (runsc) installation script and sandbox.agent.runtime frontmatter field #44795

Description

@lpcox

Summary

The compiler needs a gVisor installation script and a new sandbox.agent.runtime frontmatter field so workflows can opt into running the agent container under gVisor's runsc runtime for additional sandboxing.

AWF already supports container.containerRuntime: "gvisor" in its stdin config (PR github/gh-aw-firewall#6093). AWF translates "gvisor""runsc" internally and handles all Docker Compose plumbing, DNS workarounds, and extra_hosts injection. The compiler just needs to:

  1. Add a sandbox.agent.runtime frontmatter field
  2. Emit a gVisor install step before the AWF invocation
  3. Pass container.containerRuntime: "gvisor" in the AWF stdin config JSON

Frontmatter syntax

sandbox:
  agent:
    runtime: gvisor

AWF config mapping

The compiler should add this to the AWF stdin config JSON:

{
  "container": {
    "containerRuntime": "gvisor"
  }
}

AWF handles the translation from "gvisor" to the Docker OCI runtime name "runsc" — the compiler should NOT emit --container-runtime as a CLI flag.

gVisor installation step

The compiler must emit a pre-agent installation step that runs before AWF. This step requires sudo — see the root access section below.

Working reference implementation

This is the proven install script from the smoke-gvisor workflow (all CI runs passing):

set -euo pipefail

echo "::group::Install gVisor (runsc)"
ARCH=$(uname -m)
URL="https://storage.googleapis.com/gvisor/releases/release/latest/${ARCH}"
echo "Downloading runsc for ${ARCH}..."
curl -fsSL "${URL}/runsc" -o /tmp/runsc
curl -fsSL "${URL}/containerd-shim-runsc-v1" -o /tmp/containerd-shim-runsc-v1
sudo install -m 755 /tmp/runsc /usr/local/bin/runsc
sudo install -m 755 /tmp/containerd-shim-runsc-v1 /usr/local/bin/containerd-shim-runsc-v1
runsc --version
echo "::endgroup::"

echo "::group::Register runsc as Docker runtime"
sudo runsc install
# IMPORTANT: Must use `restart` (not `reload`).
# Docker's SIGHUP reload does NOT call setHostGatewayIP(), so
# --add-host host.docker.internal:host-gateway breaks for any
# container started after a reload-only config change.
sudo systemctl restart docker
echo "Docker runtimes:"
docker info --format '{{.Runtimes}}' || docker info | grep -i runtime
echo "::endgroup::"

echo "::group::Verify gVisor works"
docker run --rm --runtime=runsc hello-world
echo "✅ gVisor runtime verified"
echo "::endgroup::"

Critical implementation notes

Item Detail
Architecture Use uname -m directly (x86_64, aarch64). Do NOT remap to amd64/arm64 — gVisor's download URLs use raw architecture names.
Docker restart Must use systemctl restart docker, NOT reload. Docker's SIGHUP reload does not call initNetworkController() / setHostGatewayIP(), causing --add-host host.docker.internal:host-gateway to fail with ParseAddr("invalid IP").
Step ordering The install step must run BEFORE the AWF invocation step. AWF's --container-runtime gvisor sets runtime: runsc on the agent container in docker-compose.yml — Docker will fail to start the container if runsc isn't registered.
Containerd shim Both runsc and containerd-shim-runsc-v1 must be downloaded. The shim is required for Docker's containerd integration.

⚠️ Root access required — compile-time validation

gVisor installation fundamentally requires root access. The install script uses sudo for:

  • sudo install -m 755 /tmp/runsc /usr/local/bin/runsc — installs binary to system path
  • sudo runsc install — modifies /etc/docker/daemon.json to register the runtime
  • sudo systemctl restart docker — restarts the Docker daemon (system-level systemd service)

There is no rootless alternative. Docker rootless mode doesn't help because daemon.json is still root-owned and systemd --user services cannot manage the system Docker daemon.

Compile-time incompatibilities

The compiler should fail at compile time if sandbox.agent.runtime: gvisor is combined with any of these:

Incompatible option Reason
runner.topology: arc-dind ARC DinD runners use a sidecar Docker daemon with a split filesystem. gVisor requires runsc install + systemctl restart on the Docker daemon host, but the runner has no access to the DinD sidecar's daemon config or systemd. gVisor is fundamentally incompatible with ARC DinD.
sandbox.agent.sudo: false The gVisor install step itself requires sudo. While AWF can run rootless after installation, the pre-agent install step cannot be made rootless. The compiler should either reject this combination or document that sudo is required for the install step regardless of the sudo setting.

Example compile-time error messages

error: sandbox.agent.runtime: gvisor is incompatible with runner.topology: arc-dind.
       gVisor requires registering the runsc runtime with Docker via systemctl, which
       is not possible on ARC DinD runners where the Docker daemon runs in a sidecar.

error: sandbox.agent.runtime: gvisor requires root access for installation.
       Cannot combine with sandbox.agent.sudo: false.

DNS compatibility (handled by AWF)

gVisor's userspace netstack has a known DNS incompatibility (google/gvisor#7469) — Docker's embedded DNS at 127.0.0.11 is unreachable inside gVisor's isolated sandbox loopback. AWF handles this automatically when containerRuntime is set:

  • Injects extra_hosts entries for compose-internal services (squid-proxy, api-proxy)
  • Patches the chroot /etc/hosts file with topology peer IPs
  • No compiler action needed for DNS — AWF manages it end-to-end

Related

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