はじめに
GoogleからGeminiをコマンドラインで対話的に利用できる「Gemini CLI」が登場しましたね!
基本的な使い方については、すでに多くの方が素晴らしい解説記事を公開されていますので、ぜひそちらもご覧ください。
参考 zenn.dev
この記事では、Gemini CLIが備える機能の中でも、Claude Codeにはない「サンドボックス」機能に焦点を当てます。
リポジトリはこちら
この記事でわかること
- Gemini CLIのサンドボックス機能がなぜ必要なのか
- サンドボックスが有効になると、具体的に何が起きるのか
-s
フラグを付けるだけの簡単な使い方- macOSとコンテナベース、2つのサンドボックス方式の違い
1. なぜサンドボックスが必要なのか?
コーディングエージェントは、その強力さゆえに、意図しない挙動によるリスクを持ち合わせています。
例えば、次のような指示を出したとしましょう。
通常モード(サンドボックスなし)での実行
gemini -p "プロジェクト内が散らかってきたから、不要なファイルを削除してクリーンアップして"
この指示は曖昧さを含みます。もしGeminiが「不要なファイル」の解釈を誤り、ソースコードや設定ファイル、さらにはプロジェクト外の重要なファイルまで削除してしまう可能性があります。
そこで登場するのがサンドボックスモードです。
サンドボックスモードでの実行
gemini -s -p "プロジェクト内が散らかってきたから、不要なファイルを削除してクリーンアップして"
同じ指示でも、コマンドに -s
(--sandbox
) フラグを付けるだけで、Gemini CLIの動作は厳格なルールの下で実行されます。これにより、万が一Geminiが暴走しても、その影響を最小限に食い止め、システム全体を保護することができます。
サンドボックスが守ってくれるもの
サンドボックスモードを有効にすると、主に以下の3つの側面でシステムが保護されます。
ファイルシステムの保護
- ブロックされる操作: ホームディレクトリ直下の重要な設定ファイル(例:
~/.ssh/
,~/.gitconfig
)や、ドキュメントフォルダ(例:~/Documents/
)など、指定された場所以外への書き込みが禁止されます。 - 許可される操作: 現在作業しているプロジェクトディレクトリ内でのファイル操作や、一時ディレクトリへの書き込みは許可されます。
- ブロックされる操作: ホームディレクトリ直下の重要な設定ファイル(例:
ネットワークの制御
- 意図しない外部への通信を防ぐため、ネットワークアクセスを完全に遮断したり、特定のプロキシ経由の通信のみを許可したりといった制御が可能です。(詳細は後述のプロファイルで解説します)
プロセスの隔離
- サンドボックス内での操作は、ホストOSから隔離された環境で実行されます。これにより、システム全体に影響を及ぼすようなコマンドの実行が制限され、安全性が保たれます。
2. サンドボックスの基本的な使い方
サンドボックスは高度な機能ですが、その使い方は簡単です。特別な設定ファイルを用意する必要はなく、コマンド実行時にフラグを一つ追加するだけです。
起動方法
サンドボックスを有効にするには、gemini
コマンドに-s
または--sandbox
フラグを付けます。
# -s フラグを付けてサンドボックスを有効化 gemini -s -p "このコードのエラーを修正して" # --sandbox でも同様 gemini --sandbox -p "README.mdを生成して"
これだけで、Gemini CLIのすべてのツール呼び出し(ファイル操作やコマンド実行)が、保護されたサンドボックス環境内で実行されるようになります。
環境に応じたサンドボックスの自動検出
Gemini CLIは環境に応じて自動的にサンドボックスを構成します。
システムがmacOSの場合
→ OSネイティブの Seatbelt (sandbox-exec) を使用して、軽量かつ高速なサンドボックスを構築します。
DockerまたはPodmanがインストールされている場合
→ コンテナを起動し、ホストOSから完全に隔離された強力なサンドボックス環境を構築します。
3. アーキテクチャとセキュリティ
アーキテクチャとセキュリティの仕組みを詳しく見ていきましょう。
サンドボックスは、環境に応じて主に2つの方式から指定可能で、指定がなければ自動で選択されます。
- macOS Seatbelt: macOSにネイティブで組み込まれた、軽量で高速なサンドボックス。
- コンテナベース: DockerまたはPodmanを利用した、強力なプロセス隔離を実現するクロスプラットフォーム対応のサンドボックス。
方式の比較
項目 | macOS Seatbelt (sandbox-exec) | コンテナベース (Docker/Podman) |
---|---|---|
対応OS | macOSのみ | Windows, macOS, Linux |
隔離レベル | プロセスレベル(カーネルで強制) | 完全なシステムレベル(コンテナ) |
オーバーヘッド | 非常に軽量で高速 | 比較的大きい(コンテナ起動のため) |
環境 | ホストOSの環境を一部利用 | 完全に独立した環境 |
カスタマイズ性 | プロファイル(.sb ファイル)で制御 |
Dockerfile で自由に環境構築可能 |
主なユースケース | 日常的な開発作業、素早いコマンド実行 | 環境差異をなくしたい、より厳格な隔離が必要な場合 |
3.1 macOS Seatbelt (sandbox-exec
)
macOSユーザーの場合、Gemini CLIはデフォルトでOS標準の「Seatbelt」という強力なセキュリティ機能を利用します。
Seatbeltとは?
- macOS 10.5 Leopardから搭載されている、カーネルレベルで動作するサンドボックス技術です。Appleの公式アプリ(SafariやMailなど)の保護にも使われています。
sandbox-exec
というコマンドを通じて、プロセスが実行できる操作(ファイルアクセス、ネットワーク、プロセス生成など)を「プロファイル」に基づいて厳格に制限します。- OSネイティブの機能であるため、非常にオーバーヘッドが少なく、軽量に動作するのが最大のメリットです。
6つのセキュリティプロファイル
Gemini CLIは、開発シーンに合わせて独自に6つのセキュリティプロファイル(.sb
ファイル)を用意しています。これらはセキュリティレベルとネットワークアクセスの可否によって分類されており、環境変数で切り替えることができます。
使い方:
# デフォルト(permissive-open)で実行 gemini -s -p "コードを修正して" # restrictive-closedプロファイルを指定して実行(より厳格に) SEATBELT_PROFILE=restrictive-closed gemini -s -p "コードを修正して"
permissive-open
(デフォルト)- 特徴: 比較的緩やかな設定。必須ディレクトリ外への書き込みを防ぎつつ、ほとんどの操作を許可します。
- ネットワーク: 許可
- ユースケース: 通常の開発作業。
permissive-closed
- 特徴:
permissive-open
と同様のファイルアクセス権限。 - ネットワーク: ブロック (デバッガーポート
9229
のみ例外的に許可) - ユースケース: ネットワークアクセスが不要なタスク。
- 特徴:
permissive-proxied
- 特徴: 書き込み制限は有効。
- ネットワーク: 指定されたプロキシ経由 (
localhost:8877
) のみ許可。 - ユースケース: 社内プロキシなどを経由して安全に外部と通信したい場合。
restrictive-open
- 特徴: デフォルトで全ての操作を拒否し、必要なシステムコールだけを明示的に許可する厳格な設定。
- ネットワーク: 許可
- ユースケース: セキュリティを重視しつつ、ネットワークアクセスが必要な場合。
restrictive-closed
- 特徴: 最も厳しいセキュリティ設定。ファイル書き込みも最小限に制限されます。
- ネットワーク: ブロック
- ユースケース: セキュリティが最優先されるタスク。
restrictive-proxied
- 特徴:
restrictive-open
の設定に、プロキシ経由のみのネットワーク制限を追加。 - ネットワーク: 指定されたプロキシ経由 (
localhost:8877
) のみ許可。 - ユースケース: 高セキュリティとプロキシ経由の通信を両立させたい場合。
- 特徴:
3.2 コンテナベース (Docker/Podman)
macOS以外のOS、またはDocker/Podmanがインストールされている環境では、コンテナ技術を利用したサンドボックスが起動します。
特徴
コンテナベースの方式は、ホストOSから完全に隔離された環境を提供します。これにより、プラットフォームを問わず一貫した動作を実現し、非常に高いセキュリティを確保できます。
- ベースイメージ:
docker.io/library/node:20-slim
を使用し、軽量ながら必要な機能を備えています。 - プリインストールツール: 開発に必要なツール群があらかじめインストールされています。
- 基本ツール:
python3
,make
,g++
,git
,gh
(GitHub CLI) - ネットワーク:
curl
,dnsutils
,socat
- テキスト処理:
jq
,bc
,less
,ripgrep
- プロセス管理:
procps
,psmisc
,lsof
- 基本ツール:
- セキュリティ機能:
- 非rootユーザー (
node
) で実行されます。 - 機密ディレクトリ (
~/.ssh/
など) は読み取り専用でマウントされ、意図しない書き換えを防ぎます。 - ホストの環境変数がコンテナ内に引き継がれるのをフィルタリングします。
- 非rootユーザー (
3.3 全方式共通のファイル書き込み制限
macOS Seatbeltとコンテナベース、どちらの方式を選択した場合でも、ファイルシステムを保護するための共通の書き込みルールが適用されます。
書き込みが許可される主な場所:
- 現在のプロジェクトディレクトリ (
TARGET_DIR
): 作業中のフォルダ内では自由にファイルを作成・編集できます。 - システムの一時ディレクトリ (
TMP_DIR
): 一時的なファイルの生成に利用されます。 - 各種キャッシュディレクトリ:
~/.gemini/
(Gemini CLI自体の設定)~/.npm/
(npmのキャッシュ)~/.cache/
(一般的なキャッシュ)
- Git設定:
~/.gitconfig
- 標準出力:
/dev/stdout
,/dev/stderr
など
逆に言えば、これらの場所以外の重要なシステムファイルやドキュメントフォルダ(例: ~/.ssh/
, ~/Documents/
)への書き込みはブロックされるため、安心してコマンドを任せることができます。
4. 高度な設定とプロジェクトごとのカスタマイズ
4.1 サンドボックス有効化の方法と優先順位
サンドボックスを有効にするには以下の3つの方法があり、上にあるものほど優先されます。
環境変数 (最優先)
GEMINI_SANDBOX 環境変数を設定することで、CLIの挙動を強制できます。CI/CD環境などで常にサンドボックスを有効にしたい場合に便利です。
# 常にサンドボックスを有効にする (コンテナが利用可能ならコンテナ、なければSeatbelt) export GEMINI_SANDBOX=true # Dockerを明示的に指定して実行 GEMINI_SANDBOX=docker gemini -p "..."
コマンドフラグ
これまで紹介してきた -s または --sandbox フラグです。環境変数が設定されていない場合に、実行ごとに有効/無効を切り替えられます。
設定ファイル
~/.gemini/settings.json ファイルに "sandbox": true と記述することで、デフォルトでサンドボックスを有効にできます。
4.2 環境変数による詳細なカスタマイズ
Gemini CLIは、さらに細かい挙動を制御するための環境変数を多数用意しています。
SEATBELT_PROFILE
: (macOS限定) 使用するSeatbeltプロファイルを選択します。(例:restrictive-closed
)GEMINI_SANDBOX_IMAGE
: コンテナベースのサンドボックスで使用するカスタムDockerイメージを指定できます。SANDBOX_PORTS
: サンドボックスからホストに公開するポートをカンマ区切りで指定します。(例:8080:8080,9229:9229
)SANDBOX_MOUNTS
: デフォルト以外に追加でマウントしたいディレクトリを指定します。SANDBOX_ENV
: サンドボックス環境内に渡したい環境変数を指定できます。BUILD_SANDBOX
:true
に設定すると、実行前にサンドボックスイメージをローカルでビルドします。GEMINI_SANDBOX_PROXY_COMMAND
:*-proxied
プロファイルで使用するカスタムプロキシコマンドを指定できます。
4.3 プロジェクト固有の設定
環境変数だけでなく、プロジェクトのディレクトリ内に設定ファイルを置くことで、そのプロジェクト専用のサンドボックス環境を構築できます。
カスタムDockerfile: .gemini/sandbox.Dockerfile
プロジェクトルートにこのファイルを置くと、Gemini CLIはコンテナサンドボックス起動時に、このDockerfileを使って専用イメージをビルドします。プロジェクトに必要なライブラリやツール(例: terraform, kubectl)を追加するのに最適です。
起動スクリプト: .gemini/sandbox.bashrc
このファイルに記述されたシェルスクリプトは、サンドボックス環境が起動するたびに実行されます。環境変数の設定や、エイリアスの定義など、ログインシェルのように使えます。
Python仮想環境の自動マッピング
プロジェクトルートに venv や .venv といった名前のPython仮想環境ディレクトリが存在する場合、Gemini CLIはそれを自動的に検出し、サンドボックス内のPATHに追加してくれます。これにより、プロジェクト固有のPythonライブラリをシームレスに利用できます。
5. 実装レベルの深掘り
5.1 サンドボックス検出ロジック
Gemini CLIがsandbox-exec
やdocker
、podman
を呼び分けるロジックは /packages/cli/src/utils/sandbox.ts
にある getSandboxCommand
関数で実装されています。
function getSandboxCommand( sandbox?: boolean | string, ): SandboxConfig['command'] | '' { // 1. すでにサンドボックス内で実行されているかチェック (二重起動防止) if (process.env.SANDBOX) return ''; // 2. 環境変数が最優先 const envSandbox = process.env.GEMINI_SANDBOX?.toLowerCase().trim(); // (ここでenvSandboxの値に応じて'docker'などを返す処理) // 3. フラグとコマンドの存在チェック // macOSの場合 if (os.platform() === 'darwin' && commandExists.sync('sandbox-exec')) { return 'sandbox-exec'; // Dockerが利用可能な場合 } else if (commandExists.sync('docker') && sandbox === true) { return 'docker'; // Podmanが利用可能な場合 } else if (commandExists.sync('podman') && sandbox === true) { return 'podman'; } }
5.2 コンテナのマウント戦略
コンテナサンドボックスは、隔離された環境でありながら、ホストOSと連携してスムーズに作業できる必要があります。そのため、Gemini CLIは以下のディレクトリを自動的にコンテナ内にマウントします。
- 現在の作業ディレクトリ: プロジェクトファイルにアクセスできます。
- ユーザー設定ディレクトリ (
~/.gemini/
): CLIの設定を引き継ぎます。 - システム一時ディレクトリ: 一時ファイルの置き場所を共有します。
- Google Cloud設定 (
~/.config/gcloud/
):gcloud
コマンドなどが認証情報を利用できるようになります (存在する場合)。 - Application Default Credentials:
GOOGLE_APPLICATION_CREDENTIALS
環境変数が設定されていれば、その認証情報もマウントされます。 - カスタムマウント:
SANDBOX_MOUNTS
環境変数で指定された追加のディレクトリ。
5.3 ネットワークプロキシ統合
restrictive-proxied
のような制限付きネットワークプロファイルは、サンドボックス本体とは別のコンテナやプロセスでプロキシサーバーを起動し、サンドボックス内からの通信をそのプロキシに向けることで実現されています。
コンテナの場合、内部のDockerネットワークを通じて通信が行われるため、ホストのネットワークに直接露出することなく、安全に通信を中継できます。
この仕組みは拡張可能で、GEMINI_SANDBOX_PROXY_COMMAND
環境変数を使えば、自前のプロキシ実装に置き換えることも可能です。
おわりに
- サンドボックスは、強力なGemini CLIを安全に使うための機能である。
-s
フラグを付けるだけで、macOSではSeatbelt、その他ではコンテナが自動で選択され、環境が保護される。- 6つのセキュリティプロファイルや豊富な環境変数、プロジェクトごとの設定ファイルにより、セキュリティレベルと利便性を柔軟にカスタマイズできる。
なんか便利そう!
ここまで読んでいただきありがとうございました! Algomaticでは一緒に営業AIエージェントを育てる仲間を絶賛募集中です。
興味を持っていただいた方、ぜひお声掛けください!