Airflow Summit 2026 is coming August 31 - September 2 in Austin, TX. Register now to secure your spot!

airflow.providers.common.ai.sandbox.sbx

Docker Sandboxes (sbx) microVM backend for the SandboxToolset.

Attributes

log

HostNetworkPolicy

Classes

SbxSandboxBackend

Sandbox backend that runs agent commands in a Docker Sandboxes (sbx) microVM.

Module Contents

airflow.providers.common.ai.sandbox.sbx.log[source]
airflow.providers.common.ai.sandbox.sbx.HostNetworkPolicy[source]
class airflow.providers.common.ai.sandbox.sbx.SbxSandboxBackend(*, image='python:3.12-slim', memory='2g', cpus=None, sbx_path='sbx', create_timeout=600.0, host_network_policy='unknown')[source]

Bases: airflow.providers.common.ai.sandbox.base.SandboxBackend

Sandbox backend that runs agent commands in a Docker Sandboxes (sbx) microVM.

Drives the sbx CLI: create provisions a per-session microVM, exec runs commands in it, and rm tears it down. Each sandbox is a microVM with its own kernel, so agent code is isolated by a hardware boundary rather than a shared kernel. Effective isolation still depends on the image, host policy, and resource limits.

Use this for local development, not production. Docker Sandboxes is built for running coding agents against a checkout on your own machine, so driving it from an Airflow worker is off-label use. A production worker would need the sbx binary on the host, an authenticated Docker account (sbx login), a one-time sbx policy init, and on Linux, KVM or nested virtualization – which an unprivileged container cannot provide. No hosted backend ships with the provider yet; add one behind SandboxBackend if you need Kubernetes.

Network policy is a host-level setting, not a per-sandbox one. sbx governs egress through sbx policy, so this backend cannot apply a per-sandbox rule. Rather than let a DAG author believe a SandboxSpec restriction is in force when it is not, create refuses a spec it cannot honor unless the Deployment Manager states the host policy through host_network_policy.

Orphans are not reclaimed automatically. There is no server-side TTL to fall back on: if the worker is killed outright, the microVM and its workspace directory survive. Sandboxes are named airflow-sandbox-* so an operator can find and remove them; budget for that sweep before running this at scale.

The template image must provide GNU coreutils timeout, base64, stat, find, mkdir and dirname, which the command and file tools use. Any Debian or Ubuntu based image, including python:*-slim, does.

Parameters:
  • image (str) – Container image for the sandbox (sbx --template). Default "python:3.12-slim".

  • memory (str) – Memory limit in binary units (e.g. "2g"). sbx enforces a 1 GiB minimum. Default "2g".

  • cpus (int | None) – Number of CPUs to allocate. None (default) uses the sbx default, which is all host CPUs.

  • sbx_path (str) – Path to the sbx binary. Default "sbx".

  • create_timeout (float) – Seconds to allow for provisioning; first-run microVM boot plus an image pull can be slow. Default 600.

  • host_network_policy (HostNetworkPolicy) – What sbx policy is set to on this host. "unknown" (default) makes create refuse any spec that asks for a network guarantee. Set "deny-all" after running sbx policy init deny-all, or "allow-all" to state that egress is open and have specs requesting isolation refused.

name = 'sbx'[source]

Short backend identifier (e.g. "sbx"), used in the toolset id.

create(*, spec=None)[source]

Provision one sandbox and return its handle (name or id).

spec of None means “no requirements stated”: the backend applies its own defaults and makes no guarantee. It is not the same as a default SandboxSpec, which is an explicit request for an isolated sandbox. The toolset always sends a concrete spec, so None only reaches a backend a caller drives directly.

Raise SandboxTerminalError if spec asks for something this backend cannot enforce, rather than provisioning something weaker than was asked for. It is terminal rather than recoverable because it states a configuration fact the model cannot see and cannot fix by retrying.

run_command(sandbox, command, *, timeout, max_output_bytes)[source]

Run command through a shell in the sandbox, bounded by timeout seconds.

max_output_bytes bounds what the backend retains per stream while reading, so unbounded command output cannot exhaust worker memory before the toolset gets a chance to format it.

write_file(sandbox, path, content)[source]

Override: send the payload on stdin instead of in the command.

The base implementation embeds the content in the command itself, which the guest’s command-line length caps. sbx exec accepts stdin, so a large file needs no such ceiling here.

destroy(sandbox)[source]

Tear down the sandbox. Must be idempotent.

Was this entry helpful?