Skip to content

CONCEPT Cited by 3 sources

Capability-based sandbox

Definition

A capability-based sandbox is a code-execution environment that starts with no ambient authority — no network access, no filesystem access, no secrets, no ability to invoke external services — and grants each capability to the executing code explicitly, individually, through a reference the code must hold to exercise it. Absence of a capability means absence of the ability; there is no "default-on, restrict-via-list" posture.

Contrast with the traditional model: a general-purpose VM or container starts with full ambient authority (network sockets, DNS, full filesystem, environment variables, process exec) and the operator tries to constrain it via firewall rules, seccomp filters, AppArmor profiles, revocation of caps. The question "how do we stop this thing from doing too much?" applies because the thing already can do everything.

A capability-based sandbox inverts the default. As Cloudflare framed it for Dynamic Workers:

"Dynamic Workers begin with almost no ambient authority (globalOutbound: null, no network access) and the developer grants capabilities explicitly, resource by resource, through bindings. We go from asking 'how do we stop this thing from doing too much?' to 'what exactly do we want this thing to be able to do?'" (Source: Cloudflare Project Think.)

Why this is the right question for agent infrastructure

Agents execute LLM-generated code against user data. The failure modes to guard against include:

  • Prompt-injection jailbreak: attacker-controlled data in context smuggles instructions; the model emits harmful code.
  • Hallucinated destructive operations: the model misreads intent and deletes rather than reads.
  • Credential exfiltration: generated code leaks API keys via timing, logging, or exfiltration channels.

A default-deny sandbox means each of these failure modes can only cause harm through a capability the developer explicitly granted. Incremental capability grants are auditable; a default-on capability list drifts.

Capability granularity axes

  • Network egress — no default; grants are per-hostname or per- bound origin (e.g. api.github.com only).
  • Storage — no default; grants are per-bucket / per-DB / per-key-space via bindings.
  • Secrets — no default; injected by the host at call time (see patterns/agent-sandbox-with-gateway-only-egress) or via scoped bindings; never present by default in the sandbox.
  • Compute — CPU / memory / wall-clock capped by the runtime.
  • Invocation — RPC to peer services is only available through explicitly wired bindings.

The granularity determines how strongly the sandbox's posture actually constrains the code. A coarse "network on/off" toggle still lets malicious code hit anything; per-hostname is the smaller-radius grant.

Typical realisation

Project Think's Dynamic Workers are the canonical wiki instance. A fresh V8 isolate starts with globalOutbound: null (no arbitrary fetch), no DO access, no KV access, no secrets. The developer (or the agent writing a self-authored extension) declares bindings that provide exactly the capabilities needed:

{
  "name": "github",
  "permissions": {
    "network": ["api.github.com"],
    "workspace": "read-write"
  }
}

The Dynamic Worker runs with only those bindings; any other call is refused at the runtime boundary, not by a policy layer on top.

Comparison with credentialed proxy

  • Capability sandbox: the code itself cannot exercise a capability it wasn't granted. Controls the ambient space of the execution.
  • Credentialed proxy: the code can issue a call, but the credential required to make it succeed is held outside the sandbox and injected server-side after an inspection check. Controls the credential space outside the execution.

The two compose (concepts/defense-in-depth). Agent Lee uses both: the generated TypeScript runs in a Dynamic Worker (capability- based) and its outbound API calls travel through a Durable Object (credentialed proxy + read/write gate). Project Think's substrate makes the capability-based layer the default.

Why this differs from "run it in a container"

  • A container starts with a working userland, network, DNS, filesystem, environment variables — default-on. Restricting it requires explicit subtraction.
  • Container runtimes enforce isolation between containers (good) but not minimised ambient authority inside a container (orthogonal).
  • Containers take seconds to start and need hundreds of MB — too expensive for "one per code-run". Capability-based isolates start in milliseconds with a few MB (Project Think's 100× claim).

A capability sandbox can be a container if configured right; in practice the ecosystem defaults go the other way. Dynamic Workers pick the posture by construction.

Lineage

The idea predates Cloudflare — capability-security research goes back to Dennis + Van Horn (1966), Programming with Capabilities (Levy, 1984), E language / Joule / Waterken / CapnProto (Cloudflare's Kenton Varda) are all in this line. Cloudflare is applying a well-established security-kernel principle at a new layer: agent code execution in a serverless isolate.

Seen in

  • sources/2026-04-15-cloudflare-project-think-building-the-next-generation-of-ai-agents — canonical wiki instance. "The critical design choice is the capability model." Dynamic Workers' globalOutbound: null is the literal default-deny posture; explicit bindings are the capability grants. Framed as "the right question for agent infrastructure."
  • sources/2026-04-01-cloudflare-emdash-wordpress-spiritual-successor — plugin-architecture deployment. EmDash applies the capability-based-sandbox primitive to third-party CMS plugins: each plugin runs in its own Dynamic Worker with a capability manifest declaring the hooks it observes and the capabilities it needs. Extends the "agent infrastructure" use-case to "plugin infrastructure" — same primitive, different surface. The manifest + sandbox combination is what breaks the marketplace-lock-in dynamic that WordPress exemplifies.
  • sources/2026-09-28-cloudflare-emdash-10-the-stable-cms-with-a-secure-plugin-registry — 1.0 hardening + cross-platform sandbox. EmDash 1.0 makes the capability model explicit and portable across runtimes: on Cloudflare each plugin runs as a Dynamic Worker via the Worker Loader; on Node.js EmDash runs workerd as a separate process and runs each plugin as an isolated service inside it — "the same manifests and capability-gated APIs on either platform." Sharpens the independence-of-capabilities property: "giving a plugin access to media does not also expose users or unpublished content; allowing it to contact one service does not open the rest of the network… enforced by the runtime, not left to the plugin author's good intentions." Installing a plugin "feels more like installing a mobile app" — declared-then-approved capabilities. The default posture (no content/media/users/secrets/env/filesystem/network access unless declared + approved) is the literal no-ambient- authority default at the CMS-plugin layer.

Cloudflare OS refinement: observed-resource provenance (2026-08-05)

Cloudflare OS supplies a new agent-workspace deployment of the capability model. A generated app begins with no capability and receives a typed binding only for a user-granted resource; the credential remains outside generated code. It then retains resources the agent observed and uses them to constrain later sharing, derived-output rendering, egress, and delegation. The sandbox limits the initial authority; observation-coupled authorization limits subsequent use of data revealed by an allowed capability. (Source: sources/2026-08-05-cloudflare-os-an-open-platform-for-agents-apps-and-work)

Merged aliases

  • server-side-sandboxing
  • syscall-allowlist
Last updated · 766 distilled / 2,225 read