Sandbox SDK を使うと、Workers から信頼できないコードを安全に実行できます。次の 3 つの Cloudflare 技術を組み合わせて、安全でステートフル、かつ分離された実行を提供します。
- Workers - Sandbox SDK のメソッドを呼び出すアプリケーションロジック
- Durable Objects - 一意の ID を持つ永続的なサンドボックスインスタンス
- Containers - コードが実際に動く、分離された Linux 環境
flowchart TB
accTitle: Sandbox SDK のアーキテクチャ
accDescr: Cloudflare Sandbox SDK が Workers、Durable Objects、Containers を組み合わせて安全なコード実行を実現する、3 層アーキテクチャ
subgraph UserSpace["<b>あなたの Worker</b>"]
Worker["Sandbox SDK が公開するメソッドを使うアプリケーションコード"]
end
subgraph SDKSpace["<b>Sandbox SDK の実装</b>"]
DO["Sandbox Durable Object がリクエストをルーティングし、状態を保持する"]
Container["分離された Ubuntu コンテナが、信頼できないコードを安全に実行する"]
DO -->|HTTP API| Container
end
Worker -->|getSandbox が返す Durable Object stub 経由の RPC 呼び出し| DO
style UserSpace fill:#fff8f0,stroke:#f6821f,stroke-width:2px
style SDKSpace fill:#f5f5f5,stroke:#666,stroke-width:2px,stroke-dasharray: 5 5
style Worker fill:#ffe8d1,stroke:#f6821f,stroke-width:2px
style DO fill:#dce9f7,stroke:#1d8cf8,stroke-width:2px
style Container fill:#d4f4e2,stroke:#17b26a,stroke-width:2px
Workers で使う、開発者向け API です。
import { getSandbox } from "@cloudflare/sandbox";
const sandbox = getSandbox(env.Sandbox, "my-sandbox");
const result = await sandbox.exec("python script.py");目的: サンドボックスのすべての操作に、型安全でわかりやすい TypeScript インターフェイスを提供します。
サンドボックスのライフサイクルとルーティングを管理します。
export class Sandbox extends DurableObject<Env> {
// Extends Cloudflare Container for isolation
// Routes requests between client and container
// Manages preview URLs and state
}目的: 一意の ID を持つ、永続的でステートフルなサンドボックスインスタンスを提供します。
Durable Objects を使う理由:
- 永続的な ID - 同じサンドボックス ID は常に同じインスタンスへルーティングされます
- コンテナ管理 - Durable Object がコンテナのライフサイクルを所有し、管理します
- 地理的な分散 - サンドボックスはユーザーの近くで動きます
- 自動スケーリング - プロビジョニングは Cloudflare が管理します
フルの Linux 機能を備えた分離環境でコードを実行します。
目的: 信頼できないコードを安全に実行します。
コンテナを使う理由:
- VM ベースの分離 - 各サンドボックスは独自の VM で動きます
- フル環境 - Python、Node.js、Git を備えた Ubuntu Linux
SDK は、Durable Object とコンテナ間の通信に 3 つのトランスポートプロトコルを使えます。
各 SDK メソッドは、コンテナ API へ個別の HTTP リクエストを送ります。シンプルで信頼性が高く、ほとんどの用途に使えます。
// Default behavior - uses HTTP
const sandbox = getSandbox(env.Sandbox, "my-sandbox");
await sandbox.exec("python script.py");すべての SDK 呼び出しを、1 本の永続接続で多重化します。多数の同時操作をするときに サブリクエスト上限 を避けられます。
Worker の設定で SANDBOX_TRANSPORT 変数を指定すると、RPC トランスポートを有効にできます。
{
"vars": {
"SANDBOX_TRANSPORT": "rpc"
},
}[vars]
SANDBOX_TRANSPORT = "rpc"WebSocket トランスポートは非推奨です。新しいアプリケーションでは RPC トランスポートを使ってください。
トランスポート層はアプリケーションコードから見て透過です。どのトランスポートでも、SDK のメソッドは同じように動きます。各トランスポートの使い分けと設定例は、トランスポートモード を参照してください。
コマンドを実行すると、次の流れになります。
await sandbox.exec("python script.py");HTTP トランスポートの流れ:
- クライアント SDK がパラメーターを検証し、Durable Object へ HTTP リクエストを送ります
- Durable Object が認証し、コンテナへ HTTP リクエストを転送します
- コンテナランタイム が入力を検証し、コマンドを実行して出力を取得します
- レスポンス は各層を戻り、エラーは適切に変換されます
RPC トランスポートの流れ:
- クライアント SDK がパラメーターを検証し、Durable Object へリクエストを送ります
- Durable Object がコンテナへの永続接続を維持し、同時リクエストを多重化します
- コンテナランタイム が RPC メッセージを HTTP 形式のリクエストとレスポンス処理へ変換します
- レスポンス は同じ接続を戻り、エラーは適切に変換されます
Durable Object は、最初の SDK 呼び出しでコンテナへの永続接続を確立し、以降の操作で再利用します。高頻度の操作ではオーバーヘッドを減らせます。
- サンドボックスのライフサイクル - サンドボックスの作成と管理
- コンテナランタイム - 実行環境の内部
- セキュリティモデル - 分離と検証の仕組み
- セッション管理 - 高度な状態管理