Articles

Running AI Agents in GitHub Actions with Docker Sandboxes

Discover how GitHub Agentic Workflows now support Docker Sandboxes, providing an isolated, microVM-based environment for AI agents to run complex tasks safely. Learn how this integration enables secure execution of tools and integration tests within CI pipelines.

Written by:
APin

Senior Technology Analyst • Verified Expert

More from this author
Running AI Agents in GitHub Actions with Docker Sandboxes

Discover how GitHub Agentic Workflows now support Docker Sandboxes, providing an isolated, microVM-based environment for AI agents to run complex tasks safely. Learn how this integration enables secure execution of tools and integration tests within CI pipelines.

The Evolution of Agentic Isolation in CI

Continuous‑integration (CI) pipelines increasingly delegate complex tasks to autonomous agents that install tooling, execute arbitrary shell commands, and spin up dependent services such as databases. Because the agent runs on the same runner that executes the rest of the workflow, any mistake—malicious or accidental—can expand the blast radius from a single test failure to a compromised host, leaked secrets, or polluted artifact stores. Isolation therefore becomes a prerequisite for maintaining the security guarantees required by standards such as SOC 2, ISO 27001, and the NIST Cybersecurity Framework.

GitHub’s Agentic Workflows illustrate a practical isolation strategy. The workflow runs on a standard Ubuntu runner, but the agent is launched inside a Docker Sandbox (sbx) that is implemented as a dedicated micro‑VM. This micro‑VM provides its own kernel, filesystem, and private Docker daemon, so the agent can obtain root privileges and run nested containers without ever touching the host’s Docker daemon or filesystem.

  • Micro‑VM boundary: Each sandbox runs in an isolated kernel space, limiting any privilege escalation to the sandbox itself.
  • Network policy: The workflow’s network.allowed list restricts outbound connections to only the services required for the job (e.g., github, containers, java).
  • Secret injection: Secrets are injected only into the sandbox environment; the host runner never receives them directly.
  • Scoped repository access: The protected-files and allowed-files settings ensure the agent can modify only the intended source paths (e.g., src/**).

In a concrete example, an agent runs a Java integration test suite with PostgreSQL via Testcontainers. The sandbox launches a private Docker daemon, then executes:

docker run --rm \
  -e TESTCONTAINERS_HOST_OVERRIDE=host.testcontainers.internal \
  -v "$PWD:/workspace" -w /workspace \
  -v /var/run/docker.sock:/var/run/docker.sock \
  maven:3.9.9-eclipse-temurin-21 \
  mvn --batch-mode test

This command runs Maven inside a container that can communicate with the sandbox’s Docker socket, allowing Testcontainers to start a PostgreSQL instance without exposing the host daemon. After the agent fixes a seeded bug and creates a draft pull request, the sandbox is torn down, leaving no residual state on the CI runner.

By confining the agent’s autonomy to a disposable micro‑VM with tightly scoped network, secret, and file permissions, organizations can grant agents the freedom they need while keeping the overall CI environment compliant with security best practices.

Introducing GitHub Agentic Workflows (gh-aw)

The gh-aw CLI extension adds a compilation step to the standard GitHub Actions workflow lifecycle. Developers author an agentic workflow in a Markdown file whose front‑matter contains a YAML block that declares the CI environment, permissions, and the sandbox.agent runtime. The body of the file is plain English that describes the agent’s task, such as “read the requirements, run the test suite, and open a draft pull request.” When the command gh aw compile is executed, the extension parses the front‑matter, validates the schema, and emits a conventional GitHub Actions workflow file with a .lock.yml suffix. The generated workflow is indistinguishable from hand‑written actions: it uses the runs-on: ubuntu-24.04 runner, installs the Docker Sandbox tooling, authenticates the sandbox, launches the agent inside the sandbox, and performs cleanup after the job completes.

Key transformation steps performed by the compiler are:

  • Copy the on, permissions, and runs-on keys into the output YAML.
  • Insert a step that pulls the sandbox template and starts a microVM with its own Docker daemon.
  • Wrap the agent’s Markdown instructions into a run step that invokes the gh-aw runtime inside the sandbox.
  • Generate a “safe‑output” job that limits the agent’s write surface to the paths declared in protected-files and allowed-files.

Docker Sandboxes provide the native runtime for the agent. Each sandbox is a dedicated microVM that includes a private Docker daemon, its own kernel, filesystem, and network stack. This isolation ensures the agent can run containers (e.g., Maven or Testcontainers) with full root privileges inside the VM while the host runner remains protected. The sandbox’s network policy is defined in the front‑matter, allowing only the listed destinations (e.g., github, containers, java).

Practical example (excerpt from sandbox-explorer.md):

---
name: "Docker Sandboxes sample: exploratory test"
on: workflow_dispatch
runs-on: ubuntu-24.04
permissions:
  contents: read
  copilot-requests: write
sandbox:
  agent:
    id: awf
    runtime: docker-sbx
    sudo: true
  tools:
    edit: bash: ["*"]
  safe-outputs:
    create-pull-request:
      title-prefix: "[docker-sbx sample]"
      draft: true
  protected-files: blocked
  allowed-files:
    - "src/**"
---
Act as a bounded exploratory tester for this repository.
1. Read `REQUIREMENTS.md` and the relevant source files.
2. Run `./scripts/test-in-docker.sh` unchanged.
3. Add a PostgreSQL Testcontainers test for case‑insensitive email registration.
4. If the invariant fails, apply the smallest fix under `src/`.
5. Create a draft pull request containing only the new test and fix.

When compiled, the workflow installs the sandbox, runs the Maven container with the host’s Docker socket forwarded to the private daemon, executes the Testcontainers‑based integration test, and finally uses the safe‑output job to open a draft PR limited to src/**. The run logs report Docker client/server version 29.7.1, confirming that the agent operated inside the sandbox’s private daemon.

Deep Dive: The MicroVM Architecture

Modern agentic workflows require a robust isolation strategy to mitigate the security risks inherent in granting AI agents autonomous control over CI environments. The architecture of the Docker Sandbox (sbx) provides this by utilizing a microVM as the primary isolation boundary. By providing each agent with its own kernel, filesystem, and network stack, the microVM ensures that the agent's actions remain encapsulated, preventing potential breakouts from affecting the host GitHub Actions runner.

The core of this security model is the implementation of a private Docker daemon dedicated solely to the microVM. This architecture offers several technical advantages for enterprise-grade automation:

  • Granular Privilege Management: The agent is granted full root privileges within the microVM environment, enabling it to install dependencies, execute shell commands, and run complex integration test suites without requiring sudo access on the underlying CI runner.
  • Hardware-Level Isolation: Because each sandbox operates within its own microVM, the host machine remains protected from malicious or erroneous code execution. The host's Docker daemon remains entirely separate from the agent's environment.
  • Full Compatibility with Testcontainers: By running a private Docker daemon, the agent can orchestrate containerized dependencies, such as PostgreSQL databases, exactly as a developer would in a local environment. The agent interacts with its local socket, which is passed through to the private daemon, ensuring that external service dependencies do not leak into the host system.

To establish this environment, the gh-aw configuration utilizes a specific docker-sbx runtime declaration. This configuration binds the agent to the microVM while maintaining strict network egress control and explicit filesystem boundaries. The only authorized bridge between the sandbox and the host runner is the workspace directory. By enforcing these constraints through the runs-on environment and the sandbox policy, engineers can permit agents to perform high-autonomy tasks—such as finding and fixing bugs—while ensuring that the broader CI infrastructure remains shielded from the agent's operational blast radius.

Configuring Docker Sandboxes for AI Tasks

Docker Sandboxes isolate an AI‑driven CI agent inside a dedicated micro‑VM that runs its own Docker daemon. The micro‑VM provides a separate kernel, filesystem, and network stack, so the agent can obtain root privileges inside the sandbox without ever accessing the host’s Docker daemon. This isolation model satisfies common security frameworks (e.g., NIST 800‑53 SC‑7) by limiting the blast radius of arbitrary commands while still allowing the agent to install tools, start databases, and execute integration tests.

Key configuration elements

  • Runtime selection: sandbox.agent.runtime: docker-sbx tells GitHub Agentic Workflows to launch the docker-sbx runtime, which provisions the micro‑VM and injects a private Docker socket.
  • Network policy: The network.allowed list enumerates external destinations the sandbox may reach (e.g., defaults, github, containers, java). Anything not listed is blocked, enforcing a zero‑trust perimeter consistent with SOC 2 CC6.1.
  • Shell access: Setting sudo: true grants the agent unrestricted shell capability inside the sandbox. Because the sandbox is a disposable micro‑VM, this privilege does not extend to the CI runner host.
  • Safe‑output separation: The workflow splits into two jobs:
    • agent job – runs inside the sandbox, performs builds, starts Testcontainers, and writes changes only to paths declared in allowed-files (e.g., src/**).
    • safe‑output job – runs outside the sandbox with minimal permissions and creates the pull request using the create-pull-request safe‑output definition.

Practical example (excerpt from sandbox-explorer.md)

sandbox:
  agent:
    id: awf
    runtime: docker-sbx
    sudo: true
  tools:
    edit:
      bash: ["*"]
  safe-outputs:
    create-pull-request:
      title-prefix: "[docker-sbx sample] "
      draft: true
      protected-files: blocked
      allowed-files:
        - "src/**"
network:
  allowed:
    - defaults
    - github
    - containers
    - java

Inside the sandbox the agent can invoke a build container that talks to the private daemon. The following command, taken from the sample, demonstrates this pattern:

docker run --rm \
  --add-host=host.testcontainers.internal:host-gateway \
  -e TESTCONTAINERS_HOST_OVERRIDE=host.testcontainers.internal \
  -v "$PWD:/workspace" -w /workspace \
  -v /var/run/docker.sock:/var/run/docker.sock \
  maven:3.9.9-eclipse-temurin-21 \
  mvn --batch-mode test

Because the Docker socket is the sandbox’s own daemon, the Maven container can launch Testcontainers (e.g., a PostgreSQL instance) without exposing the host daemon. After the agent finishes, the safe‑output job creates a draft pull request that contains only files under src/**, preserving the repository’s integrity while still delivering the AI‑generated fix.

Practical Implementation: A Java Test Case Study

The example demonstrates a full‑stack integration test for a Java 21 registration service that must treat email addresses case‑insensitively. The test runs inside a GitHub Actions job that launches a Docker Sandbox (sbx) micro‑VM. The sandbox provides a private Docker daemon, so the agent can start containers without ever accessing the host daemon, preserving isolation while retaining full Docker capabilities.

Workflow outline

  • Sandbox provisioning: the docker‑sbx runtime creates a micro‑VM with its own kernel, filesystem and network stack. The agent receives sudo inside the VM and a mounted Docker socket (/var/run/docker.sock) that points to the private daemon.
  • Build environment: a Maven container based on Eclipse Temurin 21 is executed with the repository mounted. The command passes the Docker socket so Testcontainers can launch additional containers:
    docker run --rm \
      --add-host=host.testcontainers.internal:host-gateway \
      -e TESTCONTAINERS_HOST_OVERRIDE=host.testcontainers.internal \
      -v "$PWD:/workspace" -w /workspace \
      -v /var/run/docker.sock:/var/run/docker.sock \
      maven:3.9.9-eclipse-temurin-21 \
      mvn --batch-mode test
    
  • Testcontainers usage: the Maven test suite starts a PostgreSQL container via Testcontainers. The private daemon isolates this database from the CI host, mirroring a developer’s local environment.
  • Bug injection: the service stores emails exactly as received, while PostgreSQL enforces a case‑sensitive unique constraint. The existing integration test only checks exact duplicates, leaving the case‑insensitivity requirement unverified.
  • Agent task: the AI agent reads REQUIREMENTS.md, runs the baseline suite, adds a new Testcontainers test that registers alice@example.com and Alice@Example.com, and observes a failure (expected false, got true).
  • Automated fix: the agent modifies src/main/java/.../RegistrationService.java to normalize emails to lower‑case before persistence, re‑runs the full suite, and confirms both tests now pass.
  • Pull request creation: a draft PR is opened containing only the new test file and the one‑line normalization change, respecting the src/** patch boundary defined in the workflow.

Key takeaways for engineers

  • Using a private Docker daemon inside a sandbox enables realistic Testcontainers integration without exposing host resources.
  • Embedding the agent’s actions in a Markdown‑driven GitHub Agentic Workflow keeps configuration declarative and reproducible.
  • Limiting the agent’s output to source files (src/**) satisfies compliance frameworks such as SOC 2 or ISO 27001, which require controlled change surfaces.

Getting Started with Agentic Workflows

GitHub Agentic Workflows (gh‑aw) is a CLI extension that compiles a Markdown‑based description of an AI‑driven task into a standard GitHub Actions workflow. The compiled workflow runs on a normal ubuntu‑24.04 runner but launches a Docker Sandbox (docker‑sbx) micro‑VM. Inside that micro‑VM the agent receives root‑level Docker access while the host runner remains isolated, satisfying common AI‑isolation guidelines such as limiting network egress and secret exposure.

Installation of gh‑aw

  • Open a terminal with the GitHub CLI installed.
  • Run the official extension installer:
    gh extension install github/gh-aw
  • Verify the installation:
    gh aw --version

Configuring Docker credentials and GitHub secrets

The Docker Sandbox runtime pulls a pre‑built sandbox template from Docker Hub, so the workflow needs a Docker Hub username and a personal access token (PAT) with read:packages scope.

  • Navigate to Settings → Secrets and variables → Actions in the target repository.
  • Create two repository‑level secrets:
    • DOCKER_USERNAME
    • DOCKER_PAT
  • Alternatively, set them via the CLI (the CLI will prompt for the values):
    gh secret set DOCKER_USERNAME
    gh secret set DOCKER_PAT
  • Ensure the repository has the copilot‑requests: write permission and that “Allow GitHub Actions to create and approve pull requests” is enabled in the Actions settings.

Compiling and committing the workflow

Assume the Markdown source file is .github/workflows/sandbox‑explorer.md. The compilation step generates a locked workflow file that GitHub Actions can execute.

# Compile the Markdown into a .lock.yml
gh aw compile sandbox-explorer

# Stage both source and generated workflow
git add .github/workflows/sandbox-explorer.md \
        .github/workflows/sandbox-explorer.lock.yml

# Commit and push
git commit -m "Compile Docker Sandbox sample workflow"
git push

Running the agentic task

After the push, trigger the workflow manually or via workflow_dispatch. The CLI provides a convenient shortcut:

# Start the workflow
gh aw run sandbox-explorer

# Follow the live logs
gh run watch

The runner installs the docker‑sbx tooling, authenticates with the Docker credentials, starts the micro‑VM, and executes the agent inside the sandbox. When the job finishes, the sandbox is torn down and a safe‑output job creates a draft pull request containing only files under src/**, as defined by the protected-files and allowed-files settings.

For self‑hosted runners, ensure the host supports KVM and has Docker installed, because the sandbox requires a private Docker daemon inside the micro‑VM.

Editorial Policy & Research Methodology

Our findings are based on rigorous internal research, verified industry benchmarks, and direct technical implementation experience from our enterprise client projects. All statistics and technical claims are reviewed by senior engineers before publication to ensure accuracy, transparency, and helpfulness for our readers.

Have an Idea?

Let's Build Something Amazing Together.