Skip to content

feat: add Cloudflare sandbox provider#492

Open
roerohan wants to merge 1 commit intomattpocock:mainfrom
roerohan:feat/cloudflare-sandbox-provider
Open

feat: add Cloudflare sandbox provider#492
roerohan wants to merge 1 commit intomattpocock:mainfrom
roerohan:feat/cloudflare-sandbox-provider

Conversation

@roerohan
Copy link
Copy Markdown

Summary

  • Add a new Cloudflare isolated sandbox provider (@ai-hero/sandcastle/sandboxes/cloudflare) that runs agents in isolated Linux containers on Cloudflare's edge via the Sandbox SDK
  • Since the Cloudflare Sandbox SDK requires a Worker runtime with Durable Object bindings (cannot be used from Node.js directly), the provider communicates with a user-deployed Worker bridge over HTTP
  • Include a reference Worker bridge template in docs/cloudflare-worker-bridge/ with deployment instructions

Provider details

  • Type: Isolated (uses createIsolatedSandboxProvider, same pattern as Vercel/Daytona)
  • No peer dependency — uses plain fetch to communicate with the bridge
  • Streaming: exec() supports SSE streaming for line-by-line onLine callbacks (matching sandcastle's streaming contract)
  • Auth: Bearer token via apiToken option or CLOUDFLARE_SANDBOX_API_TOKEN env var
  • File transfer: Base64-encoded uploads for binary safety, tar+extract for directories

Worker bridge security

  • BRIDGE_API_TOKEN is required — returns 503 if not configured (no open bridges)
  • Path traversal protection — all file operations restricted to /home/user/workspace and /tmp/
  • Base64 encoding for binary file transfers to prevent corruption

Usage

import { run, claudeCode } from "@ai-hero/sandcastle";
import { cloudflare } from "@ai-hero/sandcastle/sandboxes/cloudflare";

await run({
  agent: claudeCode("claude-opus-4-6"),
  sandbox: cloudflare({
    workerUrl: "https://sandcastle-sandbox-bridge.example.workers.dev",
    apiToken: "my-shared-secret",
  }),
  prompt: "Fix the bug",
});

Files changed

File Description
src/sandboxes/cloudflare.ts Isolated provider implementation
docs/cloudflare-worker-bridge/worker.ts Reference Worker bridge
docs/cloudflare-worker-bridge/wrangler.jsonc Wrangler config
docs/cloudflare-worker-bridge/README.md Setup & deployment docs
package.json Added ./sandboxes/cloudflare export path
README.md Added Cloudflare to providers table, prerequisites, imports, reference implementations
.changeset/add-cloudflare-sandbox.md Patch changeset

Add an isolated sandbox provider that communicates with a user-deployed
Cloudflare Worker bridge wrapping the @cloudflare/sandbox SDK. The SDK
requires a Worker runtime with Durable Object bindings, so a bridge
Worker template is provided in docs/cloudflare-worker-bridge/.

Provider features:
- exec() with SSE streaming for line-by-line onLine support
- copyIn/copyFileOut via base64-encoded uploads and binary downloads
- No peer dependency — uses plain fetch to talk to the bridge
- Auth via Bearer token (option or CLOUDFLARE_SANDBOX_API_TOKEN env var)

Bridge security:
- Requires BRIDGE_API_TOKEN (503 if unset)
- Path traversal protection (restricts to /home/user/workspace and /tmp/)
- Base64 encoding for binary file transfers
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 29, 2026

@roerohan is attempting to deploy a commit to the Matt Pocock's projects Team on Vercel.

A member of the Team first needs to authorize it.

@amiranvarov
Copy link
Copy Markdown

That's really needed indeed!

agent: claudeCode("claude-opus-4-6"),
sandbox: cloudflare({
workerUrl: "https://sandcastle-sandbox-bridge.<your-subdomain>.workers.dev",
apiToken: "your-shared-secret",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems wrong to advocate putting the api token here. These run commands get committed to your repo. The cloudflare api token is supposed to be secret, so this argument should not exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants