本文へスキップ
ウェブエンジニア問題集
第5章

AIエージェントに何を許可するか — 権限設計とサンドボックス

約11分
この章の目次開く

AIエージェントを使い始めて数日で、ほぼ全員が同じ壁にぶつかります。確認を求められる回数が多すぎるという壁です。ファイルを書くたび、コマンドを打つたびに承認を求められると、作業のリズムが壊れます。

そこで多くの人が「全部許可」に倒すのですが、ここで一度立ち止まる価値があります。どこまで緩めてよいかは、モデルの賢さではなく、エージェントが置かれた環境で決まるからです。この章では、何から守っているのかを確認したうえで、権限をどう設計するかを整理します。

学習者学習者

自分が指示を出してるんだから、変なことはしないでしょ?いちいち確認されるほうが困るんだけど…

守るべき相手は「暴走するエージェント」ではない

権限設計を「エージェントが誤って危険な操作をするのを防ぐ」ものだと考えていると、設計を間違えます。より本質的な脅威は、エージェントが読んだ文章の中に、攻撃者の指示が混ざっているというものです。

これはプロンプトインジェクションと呼ばれます。名付けたSimon Willisonは、これをSQLインジェクションと同じ構造の問題だと説明しています。根本原因は、LLMが指示の出所を確実には区別できないことです。開発者が書いた指示も、ユーザーが打った指示も、Webページに埋め込まれた文字列も、すべて同じテキストとしてモデルに届きます。

警戒する人

致命的な三要素

Willisonは2025年6月、危険が現実化する条件を3つに整理しました。lethal trifecta(致命的な三要素)と呼ばれるもので、次の3つが同時に揃ったときに、攻撃者が制御するテキストがデータを外部へ持ち出せるようになります。

要素内容開発作業では何が該当するか
プライベートデータへのアクセス守りたい情報に手が届くソースコード、.env、認証情報、顧客データ
信頼できないコンテンツへの露出攻撃者が書ける文字列が届くWebページ、Issueやコメントの本文、依存パッケージ、外部APIの応答
外部への通信手段情報を外へ出せるネットワークアクセス、git push、外部APIの呼び出し

コーディングエージェントは、放っておくと3つとも揃います。リポジトリを読み、Issueやドキュメントを取得し、ネットワークにも出られる。これが標準的な構成です。

3つのうちどれか1つを切れば成立しません。最も確実な対策は、3つを同時に揃えないことです。
先生先生

「悪意のあるコードを書かせない」より、「悪意のある文章を読んでも外に出せない」を設計するほうが確実なんだ。読ませないようにするのは、現実には難しいからね。

許可には段階がある

そのうえで、日々の運用に戻ります。承認の求め方には段階があり、多くのツールが似た階段を用意しています。Claude Codeを例に取ると、次のようなモードが定義されています。

モード挙動
手動(default)ツールを初めて使うたびに確認を求める
plan読み取りと調査だけを行い、ソースを編集しない
acceptEdits作業ディレクトリ内のファイル編集や基本的なファイル操作を自動で受け入れる
auto背後の安全チェックを通したうえで自動承認する
dontAsk事前に許可したもの以外は自動で拒否する
bypassPermissions確認をほぼすべて省略する

注目すべきは、公式ドキュメントが最後のモードに付けている警告です。コンテナやVMのように、Claude Codeが被害を出せない隔離環境でのみ使うことと明記されています。組織側で disableBypassPermissionsMode を設定して、そもそも使えなくすることもできます。

権限を緩めてよいかどうかは、モデルの賢さではなく、環境が隔離されているかで決まります。

ここが実行環境の選択と直結します。使い捨ての隔離環境で動かしているなら、確認を大幅に省いても失うものは環境そのものだけです。手元のマシンで動かしているなら、同じ設定は自分の環境を賭けることになります。

禁止は許可より強い

権限ルールの設計で最初に押さえるべきなのが、評価の順序です。Claude Codeの公式ドキュメントは、ルールを deny → ask → allow の順に評価し、最初に一致したものが結果を決めると明記しています。ルールの具体性は順序を変えません。

ここから2つの帰結が出ます。

広い禁止は、狭い許可の例外を持てません。 Bash(aws *) を禁止すると、Bash(aws s3 ls) を個別に許可していてもブロックされます。禁止に穴を開けることはできない、ということです。

どのスコープの禁止も、他のスコープの許可を打ち消します。 ユーザー設定で許可していても、プロジェクト設定で禁止されていればブロックされます。逆も同様です。組織が配布する管理設定は最上位で、コマンドライン引数でも上書きできません。

分かれ道で考える人

設計としては、許可リストを広げていくより、禁止リストを先に固めるほうが安全側に倒れます。許可は「思いつかなかったもの」が抜け落ちますが、禁止は「思いついたもの」を確実に止められるからです。

権限とサンドボックスは層が違う

ここが、この章でいちばん重要な区別です。公式ドキュメントは、権限とサンドボックスを補完しあう別々の層として説明しています。

層何を制御するか効く範囲
権限どのツールを使えるか、どのファイルやドメインに触れるかすべてのツール
サンドボックスOSレベルでファイルシステムとネットワークを制限するBashコマンドとその子プロセス

この2つを分ける理由が決定的です。公式の説明を借りると、サンドボックスの制限はプロンプトインジェクションがエージェントの判断を回避した場合でも、境界の外へは出られないようにするものです。

権限ルールは、エージェントが正しく判断することを前提にした層です。判断そのものが乗っ取られたら意味をなしません。サンドボックスは判断の外側にあるので、乗っ取られても効きます。片方だけでは足りないのはこのためです。

ネットワークの出口を段階で選ぶ

致命的な三要素のうち、最も現実的に切れるのが外部への通信手段です。多くの実行環境が、外向きの通信について段階的な設定を用意しています。

段階内容向く場面
遮断外部通信を行わない(モデルとの通信を除く)依存関係が揃っていて、外部に出る必要がない作業
信頼済みのみ検証済みのパッケージ配布元などに限定する通常の開発作業の既定値
許可リスト必要なドメインだけを明示的に開ける特定の外部APIを使う作業
全開放制限なし原則として避ける

運用としては、まず絞ってから、詰まったら足すのが正しい順序です。全開放から始めて絞っていく運用は、絞るきっかけが永久に来ません。

記録を残す

権限を緩めるほど、あとから何が起きたかを追える状態が重要になります。エージェントの数が増え、非同期で走らせるようになるほど、リアルタイムで見張ることは現実的でなくなるためです。

フックを使えば、ツールの実行前後に処理を挟めます。ここでコマンドの内容と時刻を記録しておけば、想定外の操作があったときに追跡できます。権限を緩める判断と、記録を残す仕組みはセットで導入するのが実務的です。

学習者学習者

全部隔離環境でやるなら、権限の設定っていらなくならない?

隔離環境でも、エージェントはリポジトリの中身を読めますし、多くの場合は認証情報も渡されています。隔離されているのは自分のマシンであって、渡した情報ではありません。環境が使い捨てであることと、情報が守られていることは別の話です。

よくあるハマりどころ

確認を省くモードを日常運用にする。 公式が隔離環境限定と明記しているモードを、手元のマシンで常用してしまうケースです。作業は速くなりますが、事故が起きたときに戻せるものがありません。

許可リストだけを育てる。 使うたびに許可を足していくと、許可リストは膨らみ続けます。禁止側を書いていないと、一度も考えたことのない操作はすべて通る状態になります。

隔離しているつもりで、鍵ごと渡している。 前述のとおりです。環境の使い捨て可能性と、情報の秘匿は別の層です。

確率的な防御を境界だと思う。 検知の仕組みは有用ですが、それは境界ではありません。通信できないことと通信を検知できることの間には大きな差があります。

ちゃんと使うためのポイント

  • 脅威は暴走ではなく、読んだ文章に混ざった攻撃者の指示。LLMは指示の出所を確実に区別できない
  • プライベートデータ・信頼できないコンテンツ・外部への通信の3つが揃うと危険。1つ切れば成立しない
  • 権限を緩めてよいかは、モデルではなく環境が隔離されているかで決まる
  • ルールは deny → ask → allow の順で評価される。許可を広げるより禁止を固める
  • 権限は判断の層、サンドボックスは判断の外側の層。判断が乗っ取られても効くのは後者
  • ネットワークは段階で選ぶ。絞ってから足す
  • 権限を緩める判断と、記録を残す仕組みはセットで入れる

次の章では、この章で「渡している情報」として何度も出てきたシークレットそのものを扱います。環境を隔離しても、渡した鍵は隔離されません。

参考リンク