Gemini CLIでSeatbeltをカスタムして使う

に公開

Gemini CLIでSeatbeltをカスタムして使う

ちょっと前までどうやってもSeatbelt(sandbox-exec)のカスタムプロファイルを設定できなかったのですが[1]、なんかできるようになってたのでメモ。gradleプロジェクトだと~/.gradleへの書き込みが必要なのですが公式が用意したプロファイルだと書き込めず使えなかったので嬉しい修正です。

本記事から学べること

  • Gemini CLIでのsandbox設定の方法と注意点
  • macOSでのSeatbeltカスタムプロファイルの基本的な使い方
  • Seatbeltによる特定ディレクトリ読み取り拒否の設定方法
  • Gradleプロジェクト向けのプロファイルカスタマイズ例

対象読者

  • macOS上でGemini CLIを使っている人
  • 標準のプロファイルでは不十分だった人
  • dockerは重くて使いたくないがホームディレクトリを消されたくない人

カスタムプロファイルの配置

sandbox-exec用のカスタムプロファイルは、プロジェクトディレクトリ直下の.geminiフォルダ内に置きます。

  • ~/.gemini においても現状拾ってくれません。
  • ファイル名のprefixにsandbox-macos-が必要です。

設定方法

公式リポジトリにある既存のsbファイルをベースにするのが簡単です。

https://github.com/google-gemini/gemini-cli/blob/main/packages/cli/src/utils/sandbox-macos-permissive-open.sb

全てをdenyして必要なものだけallowする設定がベストではありますが、readを制限するとgemini cliを起動してshell modeでlsを使うことでさえかなりの手間がかかります。ホームディレクトリの爆破を防ぐ程度の最低限の保護でよければ、上記の公式リポジトリにある設定をベースに変更を加えていくのが楽です。[2]

Gradleを使用する場合の設定例

以下は、公式のpermissive-open設定にGradle関連のパス許可を追加したものです。
gemini-cli内でshell modeでコマンドを実行して、Operation not permittedなどが出たらそれをallowに追加していけば多分そのうちいい感じになります[3]。自分のKMPプロジェクトでは以下のように追加で3つ許可したら大体動くようになりました。
また、~/.sshの読み取りの拒否も次のようにしてできます。

.gemini/sandbox-macos-gradle.sb
(version 1)

;; allow everything by default
(allow default)

+ (deny file-read* (subpath (string-append (param "HOME_DIR") "/.ssh")))

;; deny all writes EXCEPT under specific paths
(deny file-write*)
(allow file-write*
    (subpath (param "TARGET_DIR"))
    (subpath (param "TMP_DIR"))
    (subpath (param "CACHE_DIR"))
    (subpath (string-append (param "HOME_DIR") "/.gemini"))
    (subpath (string-append (param "HOME_DIR") "/.npm"))
    (subpath (string-append (param "HOME_DIR") "/.cache"))
    (subpath (string-append (param "HOME_DIR") "/.gitconfig"))
+   (subpath (string-append (param "HOME_DIR") "/.gradle"))
+   (subpath (string-append (param "HOME_DIR") "/Library/Application/Support/kotlin"))
+   (subpath (string-append (param "HOME_DIR") "/.konan"))
    (literal "/dev/stdout")
    (literal "/dev/stderr")
    (literal "/dev/null")
)

カスタムプロファイルでの起動方法

環境変数SEATBELT_PROFILEを設定して、サンドボックスオプションを付けて起動します。

例えば、.gemini/sandbox-macos-gradle.sbを使う場合は以下のように指定します。

SEATBELT_PROFILE=gradle gemini -s

(もしくは.envSEATBELT_PROFILE=gradleを追加)

現状settings.jsonではこのプロファイルの指定はできないようです。

設定が正しく反映されている場合、以下のような表示が出ます。

MacOS Seatbelt (gradle)

以上

脚注
  1. 要出典。自環境だけかも。 ↩︎

  2. それ以上の保護が必要な場合はdocker等を利用した方が楽な感じがします。 ↩︎

  3. あるいはlog stream | grep 'deny' | grep -v -E 'oahd|airportd' でsandbox-execによって拒否された操作のログを出せます。oahd|airportdはdenyが頻発していたプロセスなので環境依存です。 ↩︎

Discussion