サンドボックス化
ランタイムは、ツールの呼び出しを OS レベルのサンドボックスでラップでき、ファイルシステムへのアクセスをワークスペースに制限し、親プロセスのシークレットへのアクセスを除去します。これは自律性システムやコマンドの許可リストとは異なります。それらはツールが実行可能かどうかを判断する_ポリシー_層であるのに対し、サンドボックスは実行中のツールが実際に実行された場合に何にアクセスできるかを制限する_メカニズム_層です。
サンドボックス設定はリスクプロファイル上に存在します。各エージェントは agents.<alias>.risk_profile を介してリスクプロファイルを参照し、エージェントのサンドボックスの有効化/バックエンドはそのプロファイルから読み込まれます。
CLI モデルプロバイダー(例: grok_cli): 外部 CLI は ZeroClaw のネイティブなツール承認フローの対象外です。上記のリスクプロファイルによるサンドボックス化では、外部 CLI を隔離できません。そのため、grok_cli ACP プロバイダーはデフォルトで --sandbox strict、--permission-mode dontAsk、および空の組み込みツールセットを注入し、ACP の権限リクエストを拒否します(CLI が reject_once を提供する場合はそれを選択し、それ以外の場合はリクエストをキャンセルします)。エイリアスの extra_args に明示的なバイパスフラグを指定すると、代わりにリクエストの allow_once オプションが選択されます。これは、Grok のアクティブな OS サンドボックスを無効にしたり、その拒否ルールを上書きしたりするものではありません。その他の権限モードでは、引き続きフェイルクローズになります。カタログ → Grok Build CLI を参照してください。
sandbox_enabled = false(または sandbox_backend = "none")を指定すると、プロファイルに追加された OS レベルのサンドボックスラッパーが無効になります。ネイティブランタイムでは、これによりツールは OS サンドボックスなしで実行されます。[runtime] kind = "docker" の場合、Docker ランタイムは引き続きコンテナー境界として機能し、docker-runtime として報告されます。これらの設定により、ランタイム自体の docker run を 2 つ目のサンドボックスコンテナーでラップすることが防止されます。リスクプロファイルを構成の残りの部分に組み込む方法については、正式な 最小限の動作例 を参照してください。
自動検出
sandbox_backend = "auto" は、起動時に利用可能な最適なバックエンドを選択します:
| プラットフォーム | 優先順位 |
|---|---|
| Linux | Landlock (カーネル 5.13 以降) → Bubblewrap → Firejail → Docker → なし |
| macOS | Seatbelt (sandbox-exec、ネイティブ) → Docker → なし |
| Windows | AppContainer(実験的)→ Docker → なし |
| 任意 | Docker(デーモンに到達可能な場合)→ なし |
特定のバックエンドを強制するには、sandbox_backend に上記のいずれかのリテラル値を設定します。
サンドボックスが制限するもの
ファイルアクセス
- 読み取りアクセス: ワークスペース、
/usr、/lib、/etc(読み取り専用)、および明示的に列挙された追加パスに制限されます。 - 書き込みアクセス: ワークスペースと
/tmpに制限されています。 - 禁止パス:
[risk_profiles.<alias>].forbidden_pathsの絶対コンポーネントプレフィックスルール。競合する許可プレフィックスと拒否プレフィックスでは、最も具体的な一致が優先され、同じ具体性の場合は拒否が優先されます。自律性のパスルール を参照してください。
ネットワーク
デフォルトでは、サンドボックス化されたツールは完全なネットワーク送信が可能ですが、インバウンドのリッスンはできません。バックエンドごとの注意事項:
- Landlock はネットワークを制御しません。ファイルシステム専用です。
- Bubblewrap と Firejail は、設定すればネットワークをブロックできます。
[runtime].kind = "docker"の場合、Docker コンテナのネットワークモードは[runtime.docker].networkに従います。
ツール固有のネットワークゲート(browser、HTTP、web_fetch)は、それぞれのツール自身の設定ブロック([browser].allowed_domains、[http_request].allowed_domains、[web_fetch].allowed_domains)に配置されます。
http_request では、プライベート/ローカルのターゲットはデフォルトでブロックされたままです。[http_request].allowed_domains を空でない状態に保ちながら、localhost や 10.0.0.1 などの名前付きプライベート/ローカルホストのみを許可するには、[http_request].allowed_private_hosts を使用してください。allowed_domains = [] は引き続きリクエストを無効化します。既存の [http_request].allow_private_hosts = true 設定は、より広範な互換性のためのオプトインとして残ります。
環境
サンドボックスは [risk_profiles.<alias>].shell_env_passthrough に列挙された環境変数のみを引き渡します。継承されたシークレットは、明示的に渡されない限りサンドボックス化されたツールには到達しません。
プロセス制限
ツールごとの実時間タイムアウトは、各ツール自身の設定ブロック([shell_tool].timeout_secs など)に記述します。Docker 固有の制限(メモリ、CPU)は、エージェントのランタイム種別が docker に設定されている場合、[runtime.docker] に記述します。
シェルバイナリ
デフォルトでは、ネイティブランタイムは /bin/sh 経由でコマンドを呼び出します。別のシェルを使用するには [runtime].shell を設定してください:
[runtime]
shell = "bash" # PATH を通じて解決されるか、絶対パスを使用します
Unix では、POSIX 互換シェルは <shell> -c "<command>" として呼び出されます。powershell/pwsh は、サポートされているすべてのデスクトップホストで PowerShell の構文とポリシーを選択し、<interpreter> -NoProfile -NonInteractive -Command <command> として実行するため、プロファイルスクリプトがポリシーを迂回してコマンドを再定義したり、プロンプトによって実行がブロックされたりすることはありません。値は、PATH 上で見つかる裸のコマンド名(例: "bash" または "pwsh")か、実行可能ファイルへの絶対パス(例: "/bin/bash")のいずれかである必要があります。区切り文字を含む相対パス(例: "./sh"、"bin/sh")は拒否されます。ランタイムの起動時に検証されるため、空、欠落、実行不可、または形式が不正なシェルは、最初のコマンドで問題を起こすのではなく、明確なエラーですぐに失敗します。未設定の場合のデフォルトは "sh" です。
Windows では、値によってファイル名からインタープリターのファミリーが選択されます。
[runtime]
shell = "pwsh" # PowerShell 7+ -> pwsh -NoProfile -NonInteractive -Command <cmd>
# shell = "powershell" # Windows PowerShell 5.x
# shell = "cmd" # または未設定のまま -> cmd.exe /C "<cmd>" (デフォルト)
powershell と pwsh(PATH によって解決される単独の名前、または "C:\\Program Files\\PowerShell\\7\\pwsh.exe" のような絶対パス)は PowerShell 経由で実行されます。それ以外の値(デフォルトの sh と明示的な cmd を含む)は、従来の動作どおり cmd.exe /C 経由で実行されます。空または空白のみの値だけが拒否され、インタープリターは spawn 時に特定されます。
シェルツール、シェルをバックエンドとするスキルツール、cron/スケジュールのシェルジョブは、すべてこのランタイム選択を使用します。ランタイムはシェルの方言もセキュリティポリシーに報告するため、ポリシーはコマンドを実行するものと同じ言語を検証します。
同じランタイム選択がモデルに報告されます。システムプロンプトの ## Runtime 行には、設定されたインタープリター (bash, zsh, pwsh, powershell, cmd) を示す Shell: フィールドが含まれます。また、登録済みツールがモデル作成のコマンド (shell, cron_add, cron_update, schedule) を受け取る場合は、## Shell セクションにそのシェルが受け付けるコマンド形式が一覧表示されるため、OS 名から推測するのではなく、PowerShell では Get-ChildItem、cmd.exe では dir /a とモデルが記述します。どちらもコマンドを構築する同じアダプターから取得されるため、報告されたシェルが実行されるものとずれることはありません。シェルアクセスのないランタイム (WASM など) では、両方とも省略されます。安全性セクションの削除に関する助言もシェルに応じて変わります。trash は、その環境に存在する場合にのみ提案されます。
PowerShell ポリシーでは、単純なコマンド呼び出し、引用符なしまたは引用符付きの引数、パイプラインからなる限定された文法が受け入れられます。$PSHOME や $PSVersionTable.PSVersion などの単純な変数の読み取りは、単独の Write-Output/echo コマンドに限られるため、後続のコマンドからファイルシステム パスを隠すことはできません。サブ式、括弧、スクリプト ブロック、型リテラル/静的メソッド呼び出し、呼び出し演算子、リダイレクト、文区切り、バックティック エスケープ、$env:NAME のようなスコープ付き変数、PowerShell プロバイダー パス、スクリプトの直接実行、ネストされたコマンド インタープリターなどの式および別の呼び出し形式は、高リスクに分類されます。PowerShell 専用のコマンド名は、複数の方言に共通するデフォルトの許可リストには追加されません。必要なコマンドレットを allowed_commands に追加するか、対応する承認設定および高リスク設定とともに “*” をオプトインしてください。既知の変更コマンドレットには中/高リスクの承認ゲートが適用されます。未知の裸のコマンドと Verb-Noun コマンドレットは、デフォルトで高リスクです。
Cron シェルジョブは、検証時と実行時の両方でグローバルなランタイム境界を継承します。ネイティブジョブは設定されたネイティブシェルを使用し、Docker ジョブは設定されたイメージ、マウント、ネットワーク、CPU、メモリ、読み取り専用ルートの設定を通じて実行されます。Cron の行に保存されるのはコマンドであり、コピーされたランタイムや方言ではありません。デーモンの再読み込みによってスケジューラとツールレジストリが再作成されると、既存のジョブは次回の実行時に新たに読み込まれた [runtime] 設定を使用します。スケジュールされた Cron の実行は再検証され、事前承認されることはありません。
ネイティブランタイム種別にのみ適用されます。Docker はコンテナのシェルを使用し、Android(常に /system/bin/sh)ではこの設定が無視され、検証も行われません。
バックエンドごとのノート
Landlock
Linuxネイティブのパス。ゼロセットアップ、カーネルで強制、非常に低いオーバーヘッド。カーネル5.13以上が必要です。
制限事項:
- ネットワークの制限なし: Landlock はファイルシステムへのアクセスのみを制御します。
forbidden_pathsは inode ベースではなくパスベースのルールで適用されるため、巧妙なシンボリックリンクによって回避される場合があります(これを緩和するため、Landlock に渡す前にリンクを解決しています)。
Bubblewrap (bwrap)
Flatpak のユーザー名前空間ベースのサンドボックス。ファイルシステムを制限し、ネットワークをブロックできます。bubblewrap のインストールが必要です。
Debian/Ubuntu
sudo apt install bubblewrap
Arch
sudo pacman -S bubblewrap
Fedora
sudo dnf install bubblewrap
Firejail
SUIDベースのサンドボックス。古くから存在し、広く利用されています。
sh
sudo apt install firejail
Firejailのデフォルトプロファイルはかなり寛容です。ZeroClawはカスタムプロファイルを適用します。追加の引数はリスクプロファイルのfirejail_argsで渡します。
Docker
Docker が動作する環境ならどこでも動作します。Docker ランタイム種別([runtime] kind = "docker")は、各シェル呼び出しを一時的なコンテナ内で実行します。イメージやリソースの制御については、上記の [runtime.docker] ブロックを参照してください。
sh
docker build -t zeroclaw-sandbox:local dev/sandbox/ # バンドルされたツールキットイメージをビルドする
利点: 強力な分離性、あらゆるOSで動作する。欠点: 呼び出しごとにコンテナの起動コストがかかる(100〜500 ms)。オーバーヘッドが許容できる本番環境でのデプロイメントに最適。
シートベルト (macOS)
ネイティブ macOS サンドボックス(sandbox-exec)。プロファイルは SBPL 形式で、ZeroClaw はツール実行用に 1 つ同梱しています。macOS 10.11 以降で動作します。
制限事項: 一部のCLIツール(古いgit、一部のHomebrewにリンクされたバイナリ)は、Seatbeltのファイルアクセスルールと正しく連携しません。macOSでエージェントのシェル呼び出しから「Operation not permitted」エラーが表示される場合、そのツールはより広範なファイルシステムへのアクセスを必要としています。Dockerへの切り替えを検討してください。
none
サンドボックス化なし。ツールは ZeroClaw サービスユーザーのフル権限で実行されます。これが YOLO モードが有効にするものです。大げさで、明白で、意図的なものです。
トラブルシューティング
- 起動時に “Sandbox backend unavailable” が表示される場合:
zeroclaw service statusとジャーナルを確認してください。自動検出機能が、試行したバックエンドをログに記録します。 - ツールが開発環境では動作するのにサービスでは失敗する: サービスユーザーは多くの場合、CLI ユーザーとは異なります。両者が必要なサンドボックス関連の権限を持っていることを確認してください(Landlock: 不要; Bubblewrap: userns 有効; Docker: サービスユーザーが
dockerグループに所属)。 - Docker ランタイムでのツール呼び出しが遅い場合: 最初の呼び出しではイメージのプルが行われますが、以降は高速になります。
docker pull <image>で事前にプルしておいてください。
コードリファレンス
- 検出:
crates/zeroclaw-runtime/src/security/detect.rs - バックエンド:
crates/zeroclaw-runtime/src/security/sandbox/(バックエンドごとに1つのファイル) - スキーマ:
crates/zeroclaw-config/src/schema.rs内のRiskProfileConfigとDockerRuntimeConfig