サンドボックス化されたコード実行
adk-sandbox クレートは、ADK エージェント向けに分離されたコード実行を提供し、次の 2 段階の分離を備えています。
- プロセス分離 — 環境分離とタイムアウト適用を備えた子プロセス
- OS レベルのサンドボックスプロファイル — ファイルシステム、ネットワーク、プロセス生成に対するカーネルレベルの制限
バックエンド
| バックエンド | 分離レベル | 言語 | 機能フラグ |
|---|---|---|---|
ProcessBackend | 環境 + タイムアウト | Rust、Python、JS、TS、コマンド | process(デフォルト) |
ProcessBackend + サンドボックス | カーネルレベル | 上記と同じ | process + sandbox-native |
WasmBackend | 完全(メモリ、ファイルシステム、ネットワーク) | WASM のみ | wasm |
どの隔離を得ていますか?
ProcessBackend::isolation() がそれを報告するため、これは crate 名から推測するものではありません:
| 結果 | 意味 |
|---|---|
IsolationClass::SubprocessOnly | 環境がクリアされ、タイムアウトが設定され、独自のプロセスグループを持つ子プロセス。OS はそれ以上の制限を適用しないため、コードはホストのファイルシステムを読み取り、ネットワークにアクセスできます。これは ProcessBackend::default() が提供するものです。 |
IsolationClass::OsEnforced | エンフォーサー と ポリシーがアタッチされるため、OS は子プロセスを制限します。 |
プロセスバックエンドについて知っておくべきことが2つあります。
- プログラムは環境がクリアされる前に解決されます。
python3、node、またはrustcのような裸のプログラム名は、呼び出し元のPATH上で検索され、絶対パスとして子プロセスに渡されます。つまり、子プロセスは起動時に独自のPATHを必要としません — 以前は、呼び出し元がPATHをExecRequest::envに設定する必要があり、それによって実行されたコードがその環境上で他のあらゆるものを起動できる状態にもなっていました。 - コンパイルは実行と同じ境界を通過します。 Rust ソースコードは以前、共有パスの外部で構築されたコマンドによってコンパイルされていたため、コンパイルにはエンフォーサーのラッパーも、タイムアウトも、プロセスグループもありませんでした。これは、コンパイルが無害な処理ではないため重要です。
include_str!はファイルを読み取り、プロシージャルマクロは生成されたバイナリが存在する前に任意のコードを実行します。コンパイルフェーズにはプラットフォーム固有のツールチェーン許可リストが渡されます。Windows では、呼び出し元がすでに Developer シェル内にいる場合を除き、インストール済みのツールチェーンから検出された MSVC および Windows SDK パスがこれに含まれます。コンパイルでは Rust ツールチェーンのrust-lldリンカーを使用するため、PATH上でそれより前にある無関係なlink.exeが選択されることはありません。OS エンフォーサーがこのフェーズを制約します。
環境の優先順位
SandboxPolicy::env はすべての実行にデフォルト値を提供し、ExecRequest::env は呼び出しごとにそれらを上書きします。以前は、ポリシーの変数は完全に無視されていました。
OS サンドボックスプロファイル
OS レベルのサンドボックス適用は、カーネルレベルで子プロセスを制限します。これは環境の分離を超えるものであり、OS 自体が承認されていないファイルシステムアクセス、ネットワーク接続、プロセスの起動をブロックします。
プラットフォームのサポート
| プラットフォーム | 強制機構 | 仕組み |
|---|---|---|
| macOS | Seatbelt (sandbox-exec) | システムコールレベルのルール:「デフォルトでは許可し、危険な操作は拒否」 — 書き込み、ネットワーク、fork を拒否します。読み取りは制限されません |
| Linux | bubblewrap (bwrap) | ファイルシステム名前空間の分離(ホワイトリスト方式のマウント) |
| Windows | AppContainer | 未実装 — 強制適用機能が利用できないと報告します |
クイックスタート
use adk_sandbox::{
ProcessBackend, ProcessConfig, SandboxBackend,
SandboxPolicyBuilder, get_enforcer,
};
// 1. Define what the sandboxed process can do
let policy = SandboxPolicyBuilder::new()
.allow_read("/usr") // Read system libraries
.allow_read_write("/tmp/work") // Write to work directory
.allow_process_spawn() // Python needs to exec
// Network is denied by default
.env("PATH", "/usr/bin:/usr/local/bin")
.build();
// 2. Get the platform-appropriate enforcer
let enforcer = get_enforcer()?;
// 3. Create a sandboxed backend
let backend = ProcessBackend::with_sandbox(
ProcessConfig::default(),
enforcer,
policy,
);
// 4. Execute code — network is blocked, writes restricted
let result = backend.execute(request).await?;
機能フラグ
[dependencies]
# Auto-detect platform enforcer
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-native"] }
# Or pick a specific platform
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-macos"] }
adk-sandbox = { version = "2.1.0", features = ["process", "sandbox-linux"] }
SandboxPolicy
ポリシーは、サンドボックス化されたプロセスに許可される操作を定義します:
| フィールド | デフォルト | 説明 |
|---|---|---|
allowed_paths | [](すべて拒否) | 読み取り専用または読み書きアクセスが可能なファイルシステムパス |
allow_network | false | ネットワークアクセスを許可するかどうか |
allow_process_spawn | false | 子プロセスの生成が許可されているかどうか |
env | {} | サンドボックス化されたプロセスの環境変数 |
プラットフォームの違い
macOS (Seatbelt): 「デフォルトでは許可し、危険な操作を拒否する」方式を使用します。完全なアクセス権から開始し、その後ネットワーク、ファイルへの書き込み、プロセスの生成をブロックします。Python は起動時に macOS 固有のシステムコールカテゴリを多数必要とするため、純粋なホワイトリスト方式は機能しません。
Linux (bubblewrap): 名前空間ベースのホワイトリスト方式を使用します。デフォルトでは何も存在せず、必要なものだけをマウントします。apt install bubblewrap または dnf install bubblewrap を使用してインストールしてください。
Windows (AppContainer): 実装されていません。設計はトークンベースの ACL です。デフォルトではアクセス権のない制限付き SID を使用し、その後、特定のパスに ACL を付与します。しかし、コンテナの作成、ACL、ケイパビリティ、ジョブオブジェクトのクリーンアップが未実装のため、probe() は EnforcerUnavailable を返します。Windows ではエンフォーサーなしで実行するか、強制適用が実際に機能する macOS または Linux を使用してください。
例
ネットワークアクセスを OS カーネルによってブロックしたサンドボックス環境で Python コードを実行する、完全な LLM-agent 駆動の例については、examples/sandbox_agent/ を参照してください。