🤖

gemini-cliで一部のコマンドだけ常に許可する

に公開

こんにちは、クラウドエースの妹尾です。

AIが発達してVibeCodingという概念ができてもう10ヵ月ほど経とうとしていますが、私も例に漏れず、すっかりAIを活用しての仕事が当たり前になっていてWSL2環境にgemini-cliを導入し、ほぼ常時稼働させている状況です。

その中で、一つだけ「少し不便だな」と感じていた点がありました。それは、コマンド実行のたびに発生する承認プロセスです。

╭──────────────────────────────────────────────────────╮
│ ?  Shell ls [current working directory /home/zdelta] │
│                                                      │
│ ls                                                   │
│                                                      │
│ Allow execution of: 'ls'?                            │
│                                                      │
│ ● 1. Yes, allow once                                 │
│   2. Yes, allow always ...                           │
│   3. No, suggest changes (esc)                       │
│                                                      │
╰──────────────────────────────────────────────────────╯

セキュリティの観点から、ツール初回実行時に承認が求められるのは普通ですし、それがあるからこそ安心してAIツールにコマンド実行を任せられるというものです。
しかし、lspsのような副作用がほとんどない頻繁に利用するコマンドも確認が必要になる上、「2. Yes, allow always ...」を選択してもセッションを変更する(geminiを再起動する)と設定が失われてしまい、再度承認を求められるのが面倒です。

そこで、ここでは全セッションで有効なホワイトリスト(許可リスト)設定機能をご紹介します。

設定ファイルの場所

リストは設定ファイルに書き込みます。
gemini-cliの設定ファイルは、環境やスコープに応じて以下の場所に配置されますので、お好みの場所の設定ファイルを編集または作成しましょう。

  1. ユーザー設定(グローバル): 全プロジェクトで有効になります。

    • Linux/macOS/WSL2: ~/.gemini/settings.json
    • Windows: C:\Users\<User>\.gemini\settings.json
  2. ワークスペース設定(プロジェクト固有): 特定のプロジェクト内でのみ有効になります。

    • プロジェクトルートの .gemini/settings.json

許可リスト(Allowlist)の設定

設定ファイルはJSON形式になっており、 tools.allowed フィールドにコマンドやツールを記述することで確認なしで実行されるようになります。
以下のような構造で投入しましょう。

~/.gemini/settings.json
{
  "tools": {
    "allowed": [
      "run_shell_command(ls)",
      "run_shell_command(git status)",
      "run_shell_command(git log)",
      "run_shell_command(git show)"
    ]
  }
}

この設定により、リストに記載されたコマンドやツールは確認なしで即座に実行されるようになり、思考を中断することなく、迅速に調査や作業を進められます。

ちなみに run_shell_command というのは gemini-cli 内部で利用されているツール名で /tools と打つことで一覧を確認できます。
また、一覧に表示されているツールであれば別のツールも確認無しで動作するように設定できます。以下は、Webページを取得する時に利用されるツールを常時許可する設定です。

~/.gemini/settings.json
{
  "tools": {
    "allowed": [
      "web_fetch"
    ]
  }
}

コマンドの一部許可

run_shell_command は、そのまま指定すると全コマンドを許可する状態になり非常に危険な設定になってしまうのですが、引数を適切に設定することで一部コマンドのみを許可するようにできます。

先の例では、run_shell_commandを完全に開放するのではなく、以下のような詳細な制御になっています。

  • lsコマンドは許可する
  • git statusgit logは許可するが、git pushrmはリストにないため許可しない
  • 他のコマンドは原則ユーザーに聞く

このように、「参照系のコマンドは自動で実行し、変更系のコマンドは人間が確認する」という、安全性と利便性を両立した運用が実現可能です。

拒否リスト(Blocklist)の設定

逆に、いかなる場合も実行を拒否したいコマンドは、tools.exclude フィールドで定義します。
ここに記載されたツールやコマンドはブロックされます。(「実行確認を常に行う」リストではないことに注意が必要です。)

なお、許可リストと併用すると拒否リストが優先されます。

settings.json の例
{
  "tools": {
    "exclude": [
      "run_shell_command(rm)",     // 'rm' コマンドの実行を禁止
      "run_shell_command(sysctl)", // 'sysctl' を使ったサービスへのアクセスを禁止
    ]
  }
}

このように、PC設定や重要なファイルの削除等を禁止することで、更に安全にツールを利用することが可能になります。
先ほども書きましたが、問答無用でブロックしてしまうので 解除する術が(設定ファイルを書き換える以外に)ない ことに注意しましょう。

設定の指針とサンプル

許可リストと拒否リストを整理する際は、以下のようなルールが参考になります。
面倒であればこのリストもGeminiに投げて、実際のJSON設定を書き出しても良いでしょう。

  • 許可リストに追加:

    • 読み込み専用のコマンド(ls, ps, git log など)
  • 拒否リストに追加:

    • システム設定を変更するコマンド (sysctl など)
    • 起動に必要なファイルを変更または削除するコマンド (rm -rf /boot など)
    • ネットワーク設定を変更するコマンド (ip, ifdown など)
    • ユーザーアカウントを変更するコマンド (passwd など)

むやみに設定すると困るコマンドに注意

また一見問題ないようなコマンドも使い方次第で危険であったり、むやみに禁止すると困ったことになる落とし穴コマンドもあります。一部を紹介します。

許可リスト編

  • sed awk
    このコマンドは、ファイルから文字列を抜き出す時に利用されることが多いですが、ファイルの内容を置き換える機能もあるのでファイル編集と同様に許可を明示的に出す必要があります。
  • rsync
    --deleteオプションがあると、パス指定ミス一発で同期先が全消去されます。「バックアップを取っておきますね」というAIの提案が、データの完全消去になる可能性があります。
  • git
    clean -fdxと一緒に使うと、.gitignore されている .env ファイルなどのローカル設定ごと消し去る可能性があるほか、勝手にリモートにpushされてチームメンバーも巻き込んでしまう可能性が高いです。 必ずサブコマンドも含めて指定しましょう。
  • chmod
    権限変更はよくあるタスクですが、指定をミスすると自身がアクセスできなくなったり、システムファイルの権限が変われば最悪起動しなくなってしまいます。

拒否リスト編

  • chmod chown
    先ほど許可リストには入れるなと書きましたが、禁止まですると「スクリプトに実行権限がないので動かない」という単純なエラーをAIが修正できなくなります。
  • rm
    ファイル削除をするコマンドですが、一律禁止してしまうとGeminiが作った一次ファイルも消せなくなってしまい利便性が損われてしまいます。
  • sudo
    管理者権限をブロックするのは当然と言えば当然ですが、AIが「sudoしていいですか?」と聞くことすらできなくなります。すると、パッケージの追加やDockerの起動、ポート開放など、環境構築の多くの場面で困難になります。
  • kill pkill
    テストのためにバックグラウンドで動かしているプログラムを停止できなくなり、テスト時のイテレーション速度が落ちます。

コマンド指定は前方一致

拒否リストは完全な防御策ではありません。
例えば ls / を拒否リストに追加しても、オプションを追加した ls -la / は許可されます。同様に、rm -rf / を防げても rm -rfv / のようにオプションを変えたり、引数の指定方法を変えることで制限を回避できてしまいます。

何故かというと、gemini-cliが内部的には コマンドの前方一致を検知して いるからです。
正規表現もありませんから、 rm/ が含まれているコマンドを拒否……といった設定はできません。
あくまで「うっかり実行」を防ぐための補助的な機能として捉え、過信しないようにしましょう。

禁止コマンドを安全に使うTips

拒否リストに載っているが、開発に頻繁に利用するコマンドがある場合もあると思います。
例えば rm を禁止したとしても、 build/cache/ を消したいケースなどです。

この場合、該当ディレクトリをクリーンアップするcleanup.shのようなスクリプトをプロジェクトに定義して、そちらを呼び出すようにGeminiに指示することで回避できます。
ただし、スクリプトファイル自体をGeminiに編集させる場合に細心の注意が必要です。

僕は Taskfile を利用して task cleanup のようなコマンドを定義してGeminiに実行させています。

Taskfile.yaml
version: '3'

tasks:
  default:
    - task --list-all
  build:
    - npm run build
  refresh:
    - npm cache clean --force
    - rm -rf node_modules
    - rm package-lock.json
    - npm install

このように定義させておき、GEMINI.md 内に「Taskfile.yamlを変更してはならない」と記載しておけば、ほぼユーザーの制御下に置くことができるはずです。

爆速コーディングのために

以上、gemini-cliの便利な設定についてご紹介しました。
AIアシスタントとの対話においてレスポンス速度は重要です。安全性を維持しつつ、不要な承認フローを省略することで、快適なAIペアプログラミング環境を構築しましょう。

それでは、良いGeminiライフを!

Discussion