sandbox ブリッジは、Sandbox SDK を HTTP API として公開する、リファレンス実装の Cloudflare Worker です。任意の HTTP クライアント(Python スクリプト、Node.js サービス、CI パイプライン)が、Worker を書かずにサンドボックスを作成・制御できます。Worker は 自分の アカウントにデプロイします。Cloudflare がホストする共有 API ではありません。
Sandbox SDK は Cloudflare Workers 内での利用を想定しています。アプリケーションが Workers エコシステムの外で動く場合、サンドボックスと直接やり取りできません。
ブリッジは Sandbox SDK を標準 HTTP API として公開するので、任意の言語やプラットフォームからサンドボックスを作成・制御できます。
主要な Sandbox SDK のメソッド は、個別の HTTP エンドポイントに対応します。ブリッジは認証、入力検証、ワークスペースパスの封じ込め、即時コンテナ起動向けの任意の ウォームプール を追加します。
ブリッジ Worker を自分の Cloudflare アカウントにデプロイします。
ボタンは Worker をデプロイし、認証用の SANDBOX_API_KEY シークレットを生成します。デプロイが終わったら、Worker の URL と API キーを控えます。このページの例では、それらを使います。
手動デプロイ
手順を追ってデプロイしたい場合は、プロジェクトを足場から作り、手動でデプロイします。
前提条件:
- Containers / Sandbox ベータが有効な Cloudflare アカウント ↗。
- Node.js ↗ と npm。
- ローカルで動いている Docker ↗ —
wrangler deployは、ブリッジのDockerfileからコンテナイメージをビルドします。
手順:
-
ブリッジプロジェクトを足場から作ります。
npm create cloudflare -- sandbox-bridge --template=cloudflare/sandbox-sdk/bridge/worker cd sandbox-bridge -
Cloudflare に認証します。
npx wrangler login -
API キーのシークレットを設定します。強いトークン値を選びます。クライアントはこの値を Bearer トークンとして送る必要があります。
openssl rand -hex 32 | tee /dev/stderr | npx wrangler secret put SANDBOX_API_KEYキーはターミナルに表示され、Wrangler にパイプされます。保存してください。API リクエストの認証に使います。
-
Worker をデプロイします。
npx wrangler deploy -
デプロイを確認します。
curl https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev/health{"ok":true}が表示されます。
ブリッジの Dockerfile は cloudflare/sandbox ↗ ベースイメージを拡張し、よく使うエージェント向けツールを事前インストールします。
- 言語: Python 3.13、Node.js、Bun
- ツール: git、ripgrep、curl、wget、jq、tar、sed、gawk、procps
ワークロードに必要な言語、システムパッケージ、ツールを追加するには、Dockerfile をカスタマイズします。
すべての例では、次の環境変数が設定済みだとします。
export SANDBOX_API_URL=https://cloudflare-sandbox-bridge.<your-subdomain>.workers.dev
export SANDBOX_API_KEY=<your-token># Create a sandbox
SANDBOX_ID=$(curl -s -X POST "$SANDBOX_API_URL/v1/sandbox" \
-H "Authorization: Bearer $SANDBOX_API_KEY" | jq -r '.id')
echo "Sandbox ID: $SANDBOX_ID"
# Run a command
curl -s -X POST "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/exec" \
-H "Authorization: Bearer $SANDBOX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"argv": ["sh", "-lc", "echo hello from the sandbox"], "timeout_ms": 10000}'
# Destroy the sandbox when done
curl -s -X DELETE "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID" \
-H "Authorization: Bearer $SANDBOX_API_KEY"const API_URL = process.env.SANDBOX_API_URL;
const API_KEY = process.env.SANDBOX_API_KEY;
const headers = {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
};
// Create a sandbox
const { id } = await fetch(`${API_URL}/v1/sandbox`, {
method: "POST",
headers,
}).then((r) => r.json());
console.log(`Sandbox ID: ${id}`);
// Run a command
// Response is a text/event-stream with the following SSE events:
// event: stdout — data is a base64-encoded output chunk
// event: stderr — data is a base64-encoded error chunk
// event: exit — data is JSON: {"exit_code": 0}
// event: error — data is JSON: {"error": "...", "code": "..."}
const execRes = await fetch(`${API_URL}/v1/sandbox/${id}/exec`, {
method: "POST",
headers,
body: JSON.stringify({
argv: ["sh", "-lc", "echo hello from the sandbox"],
timeout_ms: 10000,
}),
});
console.log(await execRes.text());
// Destroy the sandbox when done
await fetch(`${API_URL}/v1/sandbox/${id}`, {
method: "DELETE",
headers,
});# /// script
# dependencies = ["httpx"]
# ///
import os
import httpx
API_URL = os.environ["SANDBOX_API_URL"]
API_KEY = os.environ["SANDBOX_API_KEY"]
headers = {"Authorization": f"Bearer {API_KEY}"}
# Create a sandbox
resp = httpx.post(f"{API_URL}/v1/sandbox", headers=headers)
sandbox_id = resp.json()["id"]
print(f"Sandbox ID: {sandbox_id}")
# Run a command
# Response is a text/event-stream with the following SSE events:
# event: stdout — data is a base64-encoded output chunk
# event: stderr — data is a base64-encoded error chunk
# event: exit — data is JSON: {"exit_code": 0}
# event: error — data is JSON: {"error": "...", "code": "..."}
exec_resp = httpx.post(
f"{API_URL}/v1/sandbox/{sandbox_id}/exec",
headers=headers,
json={
"argv": ["sh", "-lc", "echo hello from the sandbox"],
"timeout_ms": 10000,
},
)
print(exec_resp.text)
# Destroy the sandbox when done
httpx.delete(f"{API_URL}/v1/sandbox/{sandbox_id}", headers=headers)# Write a file
curl -s -X PUT "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/file/workspace/hello.py" \
-H "Authorization: Bearer $SANDBOX_API_KEY" \
--data-binary 'print("hello world")'
# Read a file
curl -s "$SANDBOX_API_URL/v1/sandbox/$SANDBOX_ID/file/workspace/hello.py" \
-H "Authorization: Bearer $SANDBOX_API_KEY"// Write a file
await fetch(`${API_URL}/v1/sandbox/${id}/file/workspace/hello.py`, {
method: "PUT",
headers,
body: 'print("hello world")',
});
// Read a file
const content = await fetch(
`${API_URL}/v1/sandbox/${id}/file/workspace/hello.py`,
{ headers },
).then((r) => r.text());
console.log(content);# /// script
# dependencies = ["httpx"]
# ///
import os
import httpx
API_URL = os.environ["SANDBOX_API_URL"]
API_KEY = os.environ["SANDBOX_API_KEY"]
SANDBOX_ID = os.environ["SANDBOX_ID"] # from the "Create a sandbox" step
headers = {"Authorization": f"Bearer {API_KEY}"}
# Write a file
httpx.put(
f"{API_URL}/v1/sandbox/{SANDBOX_ID}/file/workspace/hello.py",
headers=headers,
content=b'print("hello world")',
)
# Read a file
content = httpx.get(
f"{API_URL}/v1/sandbox/{SANDBOX_ID}/file/workspace/hello.py",
headers=headers,
).text
print(content)ブリッジのロジックの大半は @cloudflare/sandbox パッケージにあります。最新の改善を取り込むには、次の手順を行います。
-
SDK の依存関係を更新します。
npm update @cloudflare/sandbox -
再デプロイします。
npx wrangler deploy
Dockerfile やブリッジ設定の変更で手動更新が必要な場合があるので、sandbox-sdk のリリース ↗ を確認してください。
ブリッジのソースコードと例は GitHub にあります。
- ブリッジのソース ↗ — Worker、Dockerfile、デプロイスクリプト、OpenAPI スキーマ。
- Workspace chat の例 ↗ — ファイルブラウザーのサイドバー付きフルスタックチャットアプリ。
- 基本的な例 ↗ — OpenAI Agents SDK を使ったワンショットの Python コーディングエージェント。
- HTTP API リファレンス — ブリッジ API のルート一覧です。
- 始める — Workers 上で最初のサンドボックスアプリを直接作ります。
- アーキテクチャ — Sandbox SDK が Workers、Durable Objects、Containers をどう重ねるかです。
- API リファレンス — Sandbox SDK のメソッド一覧です。
- OpenAI Agents SDK チュートリアル — ブリッジで Python コーディングエージェントを作ります。