第10章: 権限とブラスト半径 ─ 取り返しのつかない操作
2024 年の春、AI コーディングエージェントが世に出始めたばかりの頃、X (Twitter) でこんなポストが流れた。
「エージェントが
rm -rf ~を実行して、開発環境ごと消えた。今日の作業全部やり直し」
笑い話に見えて、これは設計上の本質的な問いだ。
エージェントには シェルを渡したい。npm install も git commit も pytest も走らせてほしい。
でも rm -rf や git push --force や DROP TABLE は 絶対に勝手にやらせたくない。
「便利さ」と「事故」は、同じシェルアクセスの上に乗っている。 どこに線を引くか ── これが本章の主題、permissions の話だ。
10.1 そもそも、何が怖いのか
第1章で見たとおり、エージェントは 道具 を通じて外の世界に手を出す。 道具の中身は、ファイル編集・シェル実行・ネットワーク通信 ── 要するに 普通のプログラムができることはだいたいできる。
ところで、人間の開発者は普段こういう操作を「軽く打って軽く実行」している:
rm -rf node_modules── まあ消えてもいいgit commit -m "..."── 後で直せるgit push --force── ちょっと緊張するDROP TABLE users── 本番ならクビ
人間は 後ろに戻れるか を頭の中で瞬時に判定して、慎重さのギアを切り替えている。 エージェントはこの判定を 明示的に組み込まないと、全部同じ温度で実行してしまう。
エージェントの怖さは「賢くないこと」ではない。“取り返しがつかない操作”を、“取り返しがつく操作と同じ気軽さで実行できてしまう” ことだ。
ハルシネーションが文章の中で起きるなら、笑い話で済む。
ハルシネーションが git push --force origin main で起きたら、笑えない。
10.2 二つの軸 ── reversibility と blast radius
操作の危険度を測るとき、二つの軸で考えると整理しやすい。
reversibility (可逆性)その操作を 後から取り消せるか。 ローカルファイルの編集はだいたい取り消せる (git で戻せる、エディタの undo がある)。一方、リモートに push したコミット、
rm -rfで消えたファイル、本番 DB に流したDELETEは、取り消すのが極めて難しい。
blast radius (ブラスト半径)その操作が 失敗したとき影響が及ぶ範囲。 自分のローカル作業ディレクトリだけなら半径は小さい。チームの共有 branch、本番サーバー、社内 Slack、顧客の DB に届くなら半径は大きい。「失敗の被害者が自分一人か、世界か」の話。
この二軸で操作を分類すると、こうなる:
この地図ができれば、設計判断はかなり機械的になる:
- 左上 (取り返しがつく × 狭い) ── 黙って allow してよい
- 右上 / 左下 ── 人間に 確認 を取ってから実行
- 右下 ── 原則 deny。例外時だけ人間が手で打つ
「便利か危険か」のような感情的な議論ではなく、二軸の上のどこに座標があるか で判定できるのが嬉しいところだ。
10.3 Claude Code の権限モデル ── allow / ask / deny
Claude Code は、この判定を 三段階の permission として実装している。
| 値 | 動作 |
|---|---|
| allow | 黙って実行。確認を取らない |
| ask | 実行直前に人間に確認 (y/n を聞く)。デフォルト |
| deny | 実行しない。ツール呼び出し自体をブロック |
判定の単位はざっくり ツール単位 だが、シェル系ツールについては コマンドパターン単位 で細かく書ける。
たとえば「git commit は allow、git push は ask、git push --force は deny」のように、シェルコマンドの引数も含めて指定できる。
判定の単位を「ツール一括」ではなく「コマンドパターン」まで下ろせる のが Claude Code の権限設計のキモ。 これがあるから、「Bash は使わせたいが、危険な引数だけ止めたい」という現実的な要求に応えられる。
10.4 階層 ── プロジェクト / ユーザー / セッション
permissions は 一箇所に書く ものではない。3 つの場所に書け、後から書いたものが上書きする (より制限の強い側が勝つ)。
| 階層 | どこに書く | 用途 |
|---|---|---|
| プロジェクト | リポジトリ内の設定 (チームで共有) | 「このプロジェクトでは本番 DB 系は全部 deny」 |
| ユーザー | ホームディレクトリの個人設定 | 「自分は npm install は常に allow」 |
| セッション | 起動時のフラグ、起動中の y/n 回答 | 「今日だけ gh pr merge を許可」 |
ポイントは チーム共有はプロジェクト側、個人の好みはユーザー側 という分け方ができることだ。 これによって「個人の効率」と「チームの安全」を別々のレイヤーで設計できる。
新しいリポジトリでエージェントを動かし始めるとき、まずやるべきは:
- プロジェクトに deny リスト を書く ── 本番系・取り返しのつかない系を機械的に列挙
- ユーザー側に allow リスト を書く ── 個人的に確認をスキップしたい無害な系
- セッション中は ask のままにしておく ── 想定外の操作を必ず人間に流す
このセットを最初に作るかどうかで、その後の運用の安心感が全然違う。
10.5 --dangerously-skip-permissions ── 蓋を外す覚悟
すべての確認をスキップするフラグも用意されている。名前からして強い:
--dangerously-skip-permissions
これを付けて起動すると、permissions の ask は すべて allow と同じ扱い になる。 人間に何も聞かず、エージェントが思いついた操作を全部やる。
普段は触ってはいけない。が、これが活きる場面が二つある:
- 隔離された環境 ── git worktree や Docker コンテナの中で、壊れても捨てられる作業
- CI / バッチ実行 ── 人間が画面を見ていない、対話できない環境
落とし穴「便利だから常用する」のは、第1章で見た エージェントの賢さの誤解 と同じ過ちにつながる。 LLM が完璧でない以上、ask デフォルトこそが正解 であって、
--dangerously-skip-permissionsは 箱に閉じ込めた限定的な環境 でだけ使う武器だ。特に 本番環境 や 共有 branch を触れる手 を持ったまま skip するのは、ほぼ事故と同義。
10.6 なぜ「人間に確認させる」がデフォルトなのか
permissions の哲学を一行で書くと、こうなる:
ハルシネーションのコストが小さい操作は黙ってやらせる。大きい操作だけ歯止めをかける。
LLM は確率機械であり、たまに変なツール呼び出しを出す。 出された確率を下げることは難しいが、出されてしまったときに実行されるかどうか は、外側のハーネスが完全にコントロールできる。
これはサブエージェント (第9章) と地続きの考え方だ。 サブが内部で何をしようと、そのサブにどんな道具と権限が渡っているか がブラスト半径を決める。 読み取り専用の道具しか渡していなければ、サブが幻覚を見ても被害は出ない。
実務上の鉄則は単純で:
- 読み取り系の道具は気軽に渡してよい ── Read、Grep、Glob は基本 allow
- 書き込み系は範囲を限定 ── Edit / Write は許すが、書ける場所を制限する (
add-dirの話、第Ⅱ部「コマンド: コードベース操作」で扱う) - 取り返しのつかない系は ask ── 削除、push、merge、外部送信は人間を経由
- 本番リソースに触れる手は最初から渡さない ── そもそも tool に入れない
つまり permissions の真の使い方は、「危険なものを止める」よりも「最初から危ないものを手渡さない」 ことに近い。 止める仕組みは事故防止の最後の砦であり、第一の防御は 道具セットの設計 の側にある。
10.7 この章の振り返り
- エージェントの怖さは「賢くない」ではなく「取り返しのつかない操作を軽い操作と同じ温度で実行できる」こと
- 操作は reversibility (可逆性) と blast radius (ブラスト半径) の二軸で分類できる
- Claude Code の権限モデルは allow / ask / deny の三段階
- 判定単位はツール単位だけでなく コマンドパターン単位 まで下ろせる
- 設定は プロジェクト / ユーザー / セッション の三階層
--dangerously-skip-permissionsは 隔離環境・CI 専用 の武器。常用は事故のもと- 第一の防御は止める仕組みではなく 道具セットの設計 ── 危ないものは最初から渡さない
この章で読めるようになるツイート / ブログ
- 「エージェントに
git push --force食らわされて主 branch が壊れた」 → 右下象限の操作を allow にしていた典型事故。プロジェクト側で deny を書くべきだった例 - 「
--dangerously-skip-permissions付けたら一気に速くなった、最高」 → 隔離 worktree や CI なら正解。共有 branch を触れる環境でやれば事故が時間の問題 - 「Read だけ allow、Bash は ask にしてる」 → 二軸地図でいうと「読み取りは左上、シェルは未知数」と分けた賢い設定
- 「sub-agent には書き込み道具を渡さない運用にした」 → ブラスト半径を限定する設計判断。本章の最終節そのもの
次章では、permissions だけでは足りない「ツールの実行前後に必ず何かを差し込みたい」という要求を扱う。 たとえば「commit 前に必ず lint を走らせたい」「Write の後に formatter を流したい」 ── これを実現するのが hooks だ。