FabricFabricHarness
Reference

Sandboxes matrix

Every supported sandbox backend at a glance — what it gives you, the example, and the one-liner to enable it.

A sandbox is where shell commands and tool calls execute. It's chosen at init({ sandbox }) and is independent of which SDK entrypoint you import from and which runtime you select.

SandboxWhat it gives youEnable withExample
virtual (default)In-memory FS + bash subset (grep, glob, read, cat, mkdir, rm, echo) via just-bash. No host shell access.injected by default; init({ sandbox: 'virtual' }) to be explicitexamples/hello-world/
localHost filesystem and host shell at the session's working directory.init({ sandbox: 'local' })examples/with-local-shell/
dockerPer-session Docker container; reads/writes scoped to the container.init({ sandbox: { backend: 'docker', image: 'node:22' } })examples/with-docker/
cloudflareCloudflare Sandbox container binding for Workers. Edge-native.init({ sandbox: createCloudflareSandboxEnv(getSandbox(env.Sandbox, sessionId)) }) (getSandbox from @cloudflare/sandbox, adapter from @fabric-harness/cloudflare)examples/with-cloudflare-sandbox/
Temporal-driven localRuns through Temporal workflows for replay-determinism, restartability, approvals.import { defineAgent } from '@fabric-harness/sdk/strict' + init({ runtime: 'temporal', sandbox: 'local', compaction: { enabled: false } })examples/with-temporal/
Azure Foundry HostedAzure-managed agent runtime; Key Vault secrets, Foundry observability.AzureOpenAIModelProvider + fabric-harness build --target foundry-hosted-agentexamples/with-azure/
DaytonaDaytona-managed remote dev sandbox. Per-task ephemeral box.init({ sandbox: daytonaSandbox(remote, { cleanup: true }) }) (from @fabric-harness/connectors)examples/with-daytona/
E2BE2B remote sandbox; native pause/resume.init({ sandbox: e2bSandbox(remote, { cleanup: true }) }) (from @fabric-harness/connectors)recipe connectors/sandbox--e2b.md
ModalModal serverless sandbox; per-request GPU.init({ sandbox: modalSdkSandbox(remote, { cleanup: true }) }) (from @fabric-harness/connectors/modal)examples/with-modal/
Vercel SandboxVercel's ephemeral container compute with streamed output, abort, and portable refs.init({ sandbox: vercelSandbox(remote, { cleanup: true }) }) (from @fabric-harness/connectors/vercel)examples/with-vercel-sandbox/
Kubernetes / AKSKubernetes pod via kubernetesSandbox(pod, …) (or aksSandbox from @fabric-harness/azure).init({ sandbox: kubernetesSandbox(pod, { cleanup: true }) }) (from @fabric-harness/connectors/k8s)examples/with-kubernetes/
Databricks SQLSQL Warehouse exec-only sandbox; session.shell() executes SQL, not bash.init({ sandbox: databricksSqlSandbox({ host, token, warehouseId }) }) (from @fabric-harness/databricks/sql-sandbox)Databricks SQL sandbox
emptyNo filesystem, no shell — pure model + tool-call work.init({ sandbox: 'empty' })n/a

Provider-backed sandboxes require provider credentials, lifecycle permissions, and the smoke test documented on their setup page. For Databricks SQL, validate Warehouse connectivity and Unity Catalog grants in the target workspace.

Certification levels

Adapter implementation, contract coverage, and credentialed live certification are separate. A hosted provider is live-certified only when every advertised supported SDK major has a retained report with all nine checks passed: shell, binary file, cwd/environment, streaming output, timeout, abort, portable reference, reconnect, and cleanup. Skips and structural mocks do not satisfy that claim.

Protected CI reads provider credentials from the sandbox-live GitHub Environment, validates the report against SANDBOX_PROVIDER_COMPATIBILITY, verifies that the report version is the package actually installed in the run, and emits a digest manifest. Re-certify after SDK-major, credential, account-binding, or lifecycle changes. A provider without current credentials remains available as an adapter but must be described as unverified rather than live-certified.

Cross-process refs. Remote backends (E2B, Daytona, Modal, Vercel, Kubernetes, Cloudflare Sandbox, and Cloudflare Shell with a routing ID) can be re-attached from another process with session.sandboxRef({ portable: true }) + attachSandbox(serialized) after registering the receiving-process decoder. See @fabric-harness/connectors/sandbox-refs.

Picking a sandbox

  • One-shot webhook / edge workervirtual (cheap, fast, no host) or cloudflare (Workers).
  • CI job, dev boxlocal.
  • Coding agent / untrusted shell workdocker, daytona, or modal.
  • Long-running, restartable — Temporal-driven local (use /strict).
  • Compliance / Azure tenant — Azure Foundry Hosted Agent.
  • Governed analytics where shell means SQL — Databricks SQL sandbox.

Capability axes

Every sandbox declares a SandboxCapabilities shape so agents can adapt:

sandbox.capabilities // { exec, network, filesystem, snapshot, ... }

Use this when an agent legitimately needs to know whether shell exec is available before issuing a command.

See also