Works
Blog Recruit Contact AI互換性診断
セキュリティ
calendar_today
[AIエージェント時代の権限設計 Vol.2] 山下 太郎 山下 太郎

AIエージェント時代の権限設計 第2回:最小権限原則をAIエージェントに適用する難しさ ― 古典原則が当てはまらない4つの理由

削除・外部送信・金融API操作の権限分離、開発DBと本番DBの分離、ロール定義のチェックリスト。Replit事件が示した「広すぎる権限」の代償から最小権限原則の実装を逆算する連載②第2回。

AIエージェント時代の権限設計 第2回:最小権限原則をAIエージェントに適用する難しさ ― 古典原則が当てはまらない4つの理由

第1回では、AIエージェントを「道具」ではなく「準社員」として扱う必要性を論じました。エージェントに固有のIDを発行し、責任者を割り当て、ライフサイクルを定義する——この主体性の整備が、連載②全体の前提条件でした。

本記事は、その主体性が確立されたエージェントに対して、「何を許し、何を許さないか」を書く段階に入ります。

主体に対する権限スコープの設計。古典的なIT統制の世界では、これは「最小権限原則(Principle of Least Privilege、PoLP)」と呼ばれ、半世紀の歴史があります。1975年にJerome SaltzerとMichael Schroederが提唱した8つの設計原則の一つで、ISO/IEC 27001NIST SP 800-53CIS Controlsといった主要セキュリティフレームワークすべての中核に位置づけられている、最も基本的な原則です。

ところが、この古典原則をAIエージェントに当てはめようとすると、なぜか空転します。原則の意義を否定する組織はないのに、実装が進まない。連載①第5回で挙げた4つの共通設計欠陥のうち、最初に挙がったのが「権限が広すぎる」でした。Moltbookも、Lovableも、Replitも、すべてこの構造で発火しています。

なぜか。本記事は、この空転の正体を4つの構造的難しさとして整理し、その上で、それでも実装するためにどうするか——3つの危険動作カテゴリの分離、開発と本番の認証情報分離、職務記述書という具体的な処方に翻訳します。

連載①第5回で挙げた4つの共通設計欠陥のうち、本記事は①「権限が広すぎる」を技術的実装レベルで処方します。残り3つ(シークレット直書き、人間承認の欠如、AI応答の無批判受容)は、それぞれ第3回・第4回で扱います。

1. 最小権限原則とは何か ― 半世紀の古典

最小権限原則の定義は、極めてシンプルです。

あらゆるプログラム、およびシステムの特権ユーザーは、業務を完遂するために必要な最小限の特権のみで動作すべきである。

これは1975年、SaltzerとSchroederが論文「The Protection of Information in Computer Systems」で提示した8つの設計原則の一つとして登場しました。50年経った現在も、ISO/IEC 27001NIST SP 800-53 Rev. 5(2025年8月にRelease 5.2.0としてマイナー更新)、CIS Critical Security Controls v8.1、PCI DSS、SOC 2 Type II——主要なセキュリティ統制フレームワークのすべてが、この原則を中核に据えています。

実装の言葉に翻訳すると、こうなります。

  • 読み取りで足りる業務には、書き込み権限を与えない
  • 特定のテーブルしか参照しない業務には、他テーブルの読み取り権限を与えない
  • 本番環境を変更する必要のない業務には、本番環境への接続権限を与えない
  • 金融トランザクションを扱わない業務には、決済APIへのアクセス権限を与えない

人間社員に対しては、これは比較的素直に実装できます。経理部の社員は会計DBを読めますが、本番環境のデプロイはできません。情シス部のロール管理者は権限変更ができますが、顧客の決済情報は触れません。職務記述書から逆算して、権限スコープを書ける構造があります。

そして、この50年の積み重ねを、AIエージェントに延長するだけ——のはずでした。エージェントを準社員として認知する(第1回で確立)。職務記述書を書く。権限スコープを定義する。それを技術的に実装する。古典原則の素直な拡張に見えます。

ところが実際は、空転します。なぜか。

2. 難しさ① 必要権限が事前に確定しない ― 振る舞いの非決定論性

最初の障壁は、AIエージェントの振る舞いが非決定論的であることです。

人間社員に職務記述書を書くとき、私たちは暗黙に「この職務は決定論的だ」と仮定しています。経理部の社員が「会計DBを読む」と書かれているとき、その社員が日々何をするかは、ある程度予測可能です。月次決算のときは特定のテーブルを集計し、四半期報告のときは別のクエリを実行する。職務の中身は変動しますが、使うリソース・実行するアクションの集合は、ほぼ事前に列挙できます。

AIエージェントには、この前提が成立しません。

同じプロンプト「先月の売上をサマリーして」に対しても、エージェントは状況によって異なる経路を取ります。あるときはSELECT SUM(amount) FROM sales WHERE month = ...を実行する。別のときは、複数のテーブルをJOINして集計する。さらに別のときは、外部APIを呼び出して為替レートを取得し、複数通貨の合計を計算する。同じタスクでも、文脈・状態・確率分布の揺らぎによって、選ぶツールも経路も変わります。

これは「エージェントの欠陥」ではありません。エージェントの定義そのものです。固定の手順だけを実行する装置は、エージェントではなくスクリプトです。エージェントが価値を持つのは、状況に応じて経路を選べることに起因しています。

しかし、最小権限原則は逆を要求します。「事前に必要な権限を、過不足なく列挙せよ」と。これが、第一の根本的な衝突です。

設計者は2つの選択肢に直面します。

flowchart TD A[AIエージェントの<br/>必要権限の事前確定] --> B{選択肢} B --> C[選択肢A:<br/>「想定される全ケースを列挙して<br/>権限を広めに付与する」] B --> D[選択肢B:<br/>「最小限に絞り、<br/>不足したら都度追加する」] C --> E[本番リリース後<br/>誰も棚卸ししない] E --> F[広すぎる権限が<br/>固定化される] D --> G[「権限がありません」<br/>エラーが頻発] G --> H[ユーザー満足度低下<br/>運用負荷増大] H --> I[結局、選択肢Aへ流れる] F --> X[Replit型・Moltbook型の<br/>事故が発火しうる状態] I --> X style C fill:#fa3 style F fill:#fa3 style X fill:#c00,color:#fff

実務でほぼ常に選ばれるのは選択肢Aです。理由は単純で、選択肢Bは初期構築コストと運用負荷が大きく、しかもユーザー(多くの場合、開発者自身)から見て「動かない」体験を生むからです。

そして選択肢Aを選んだ瞬間、Moltbook・Lovable・Replitと同じ構造に置かれます。「広めに付与した権限が、誰にも棚卸しされないまま本番に固定化される」状態です。

これが、最初の難しさです。最小権限原則は「必要権限を事前に確定できる」ことを前提にしている。AIエージェントは、その前提を満たさない

3. 難しさ② 学習データに基づく経路探索 ― 想定されないツールが呼ばれる

第二の難しさは、AIエージェントが学習データに基づいて経路を探索することから来ます。

古典的なソフトウェア統制では、「Aロールの社員は、Xリソース・Yツール・Zコマンドを使える」というホワイトリスト方式で権限を書きます。リストに載っているもの以外は使えない。リストに載っているものの中で、社員は決まった手順で仕事をする。

AIエージェントは違います。AIエージェントは、利用可能なツール集合(許可されたMCPサーバー、API、コマンド群)を自分で組み合わせてタスクを完遂します。組み合わせ方は、学習データから引き出されます。学習データには、世界中の開発者が「この問題に直面したらこう解決した」という典型的なパターンが、大量に含まれています。

つまりAIエージェントは、ホワイトリストの中で「想定されない経路」を作りうる。しかもその経路は、エージェント自身の発明ではなく、学習データに含まれていた「他の開発者の典型的な行動」です。

連載①第4回で見たReplit事件は、これの教科書的な実例です。Replit AIエージェントは「コードフリーズ中」と何度も指示されていました。それでも、空のクエリ結果を観測した瞬間、npm run db:push --forceという破壊的コマンドを生成しました。なぜか——学習データ中で、開発者が「DBが空」を見たときに最も頻繁に取る行動が、「再構築・再投入」だからです。

このコマンド自体は、Replitのエージェントが使えるツールセットに含まれていました。npmは実行可能、db:pushスクリプトは存在、--forceフラグは有効。個々のツールはホワイトリストに載っていた。問題は、それらが組み合わさったときに、「コードフリーズ」という意図に反する経路が生まれたことです。

これは、古典的IT統制が想定していない事象です。古典的統制では、「許可されたツールAと許可されたツールBの組み合わせが、許可されていないアクションCを生む」という事態を、設計時に網羅的に予測できる前提でした。人間社員に対しては、この前提はだいたい成立します。社員は「許可された組み合わせ」だけを試みるからです。

AIエージェントには、この前提も成立しません。エージェントは、ホワイトリストの中で確率分布的に最適と思われる経路を選びます。「最適と思われる」基準は、学習データの統計に依存しており、組織のセキュリティポリシーに依存していません。

flowchart TB A[エージェントに<br/>許可されたツール集合] -->|ホワイトリスト方式| B[A: bash<br/>B: npm<br/>C: psql<br/>D: curl<br/>E: SELECT文] B -->|学習データに基づく<br/>経路探索| C{典型パターン} C -->|空DB → 再構築| D[npm run db:push --force] C -->|認証情報必要 → 探す| E[grep -r 'API_KEY' / .env] C -->|外部送信必要 → POST| F[curl -X POST https://...] D --> X1[本番DB破壊] E --> X2[シークレット露出] F --> X3[データ外部送信] style B fill:#3a7 style D fill:#c00,color:#fff style E fill:#c00,color:#fff style F fill:#c00,color:#fff

ホワイトリストに載っている個々のツールは安全に見えます。しかし、それらが学習データの典型パターンによって組み合わされた瞬間、想定されない経路が生まれる。最小権限原則は、ツール単位の権限を絞ることに長けていますが、ツール組み合わせの経路を縛る仕組みを持っていません

これが、第二の難しさです。

4. 難しさ③ 過剰権限がエラーとして顕在化しない ― 動くから気づかない

第三の難しさは、過剰権限の検出可能性に関わります。

古典的IT統制では、権限不足はすぐに発見されます。社員が業務に必要なリソースにアクセスできなければ、エラーが返ってきます。社員は情シス部に「アクセス権を付けてください」と依頼します。これが正常なフローです。

逆に、過剰権限の発見は、ずっと難しい。なぜなら、過剰権限は「使わないだけ」だからです。経理部の社員に、本番DBへの書き込み権限が誤って付いていても、その社員が業務でそれを使わなければ、エラーは出ません。誰も気づきません。年に一度のIT監査か、退職時の権限棚卸しで、ようやく発見される——ことが多い。

AIエージェントの場合、これがさらに深刻になります。

理由①:エージェントは「動かす」方向に最適化されている

連載①第1回で見たコロンビア大学DAPLabの研究が指摘した通り、AIは「ユーザーに受け入れられること」に最適化されています。エラーを消すのが最短経路の場合、AIはエラーを消そうとします。これは過剰権限を歓迎する性向です。エラーが出ない=動く=ユーザー満足、という確率分布の頂点に向かって、エージェントは権限を最大限に活用します。

理由②:エージェントは権限不足を「自動的に回避する」

人間社員と違って、AIエージェントは権限不足のエラーに直面しても、情シス部に依頼するという選択肢を取りません。代わりに、別の経路を学習データから探します。たとえば「このAPIがダメなら、別のAPIで似た情報を取れないか」「このDBがダメなら、設定ファイルから直接読めないか」。権限不足が組織に伝わる前に、エージェントが自分で迂回することが多発します。

flowchart TB A[人間社員が<br/>権限不足に直面] --> B[エラーを情シスに報告] B --> C[棚卸しの機会が発生] D[AIエージェントが<br/>権限不足に直面] --> E[学習データから<br/>別の経路を探す] E --> F[エラーを内部処理して<br/>タスク完遂] F --> G[組織には伝わらない] H[結果: 過剰権限は使われ続ける] --> I[本来不要な権限が<br/>「動いているから問題ない」<br/>として残置される] C -.正常な統制サイクル.-> J[棚卸しが機能する] G -.統制サイクルの<br/>断絶.-> H style C fill:#3af style G fill:#fa3 style I fill:#c00,color:#fff

理由③:AIエージェントの活動ログは検証が難しい

AIエージェントが何を実行したかのログは取れます。しかし、そのログから「この権限は本当に必要だったか」を判断するのは、人間社員のログを見るときよりも難しい。エージェントの行動は、確率分布の上で生成されているため、「今回はたまたま使ったが、毎回使うわけではない」というケースが多発します。これは「次回も必要か」の判断を曇らせます。

結果として、AIエージェントの過剰権限は、動いている限り誰も気づかず、年単位で組織に蓄積していきます。事故が発火するときに、初めて棚卸しされる——Moltbook、Lovable、Replitすべてに共通するパターンです。

これが、第三の難しさです。

5. 難しさ④ 市場インセンティブとの衝突 ― 「動く」は報酬される、「絞る」は処罰される

最後の難しさは、技術的というより経済的・組織的なものです。

連載①第3回で見たように、vibe codingプラットフォーム市場全体が「動く」ことを報酬する構造になっています。これは個別のプラットフォームの問題ではなく、市場のインセンティブ構造の問題です。

最小権限原則を厳格に適用すると、AIエージェントの開発体験は、確実に重くなります。

  • エージェントが「権限がありません」エラーを出す頻度が上がる
  • 開発者は権限を追加申請する必要がある
  • 申請には承認プロセスが伴う
  • プロトタイプから本番までの距離が伸びる

ユーザー(多くの場合、開発者自身)から見ると、これは「動かないAIエージェント」に映ります。連載①第1回で見たLemkin氏のDay 1の興奮——「Deploy」をクリックして瞬時にライブになる、というドーパミンヒット——とは、対極の体験です。

そして開発者は、たいてい時間に追われています。期限に追われた開発者は、権限を厳格に絞るより、緩めに付与して「とりあえず動かす」を選びます。これは個人の倫理の問題ではなく、合理的な意思決定の結果です。

組織レベルでも同じ力学が働きます。セキュリティ部門が「最小権限を厳格に」と主張しても、事業部門は「それで動かなくなったら、競合に追い越される」と反論します。連載①第3回でReplit CEO Masad氏とLovable CEO Osika氏の応酬を見た通り、市場で「動く」を競っている企業に、「安全」のために減速するインセンティブはほとんどありません。

これが、第四の難しさです。最小権限原則は、それを支持する論理は十分にあるのに、それを実装する経済的・組織的な力学が働きにくい

ここまでが、最小権限原則がAIエージェントに対して空転する4つの構造的理由です。整理すると、こうなります。

難しさ古典的前提AIエージェントの実態
① 必要権限の事前確定不能職務は決定論的、必要権限は列挙可能振る舞いは非決定論的、列挙不可能
② 想定されない経路ホワイトリスト内で社員は予測可能に動く学習データの統計でツールが組み合わさる
③ 過剰権限が顕在化しない棚卸しサイクルで検出されるエージェントが自動回避するため検出されない
④ 市場インセンティブとの衝突セキュリティと業務効率は別レイヤ「動く」を絞ると競争力低下と直結

ここで重要なのは、これらの難しさは「最小権限原則を捨てる理由」ではなく、「素直な拡張では空転するから、実装の翻訳が必要」という診断であることです。次節以降は、この翻訳に入ります。

6. Replit事件を権限設計レンズで再解読 ― 4つの失敗の重ね合わせ

具体的な処方に進む前に、Replit事件をもう一度開きます。連載①第4回では、Replit事件を「鏡としてのAI」「自然言語の指示は権限制御にならない」というレンズで読みました。同じ事件を権限設計レンズで読み直すと、4つの構造的失敗が浮かびます。

flowchart TD A[Replit事件<br/>本番DB全消去・1,206名・1,196社] --> B[失敗1<br/>━━━━━━<br/>主体の未確立<br/>開発者の人間IDが<br/>エージェントに継承] A --> C[失敗2<br/>━━━━━━<br/>削除権限が<br/>読み書き権限と<br/>分離されていない] A --> D[失敗3<br/>━━━━━━<br/>開発DBと本番DBが<br/>認証情報レベルで<br/>分離されていない] A --> E[失敗4<br/>━━━━━━<br/>「コードフリーズ」が<br/>自然言語の指示で<br/>システム制約ではない] B -.第1回で扱った.-> F[主体性整備の不在] C -.本記事で扱う.-> G[3カテゴリ分離] D -.本記事で扱う.-> H[動的シークレット注入] E -.第3回で扱う.-> I[ヒューマン・イン・ザ・ループ] style A fill:#c00,color:#fff style B fill:#fa3 style C fill:#fa3 style D fill:#fa3 style E fill:#fa3 style F fill:#3af style G fill:#3af style H fill:#3af style I fill:#3af

失敗1(主体の未確立)は、第1回で扱いました。エージェントが開発者IDの拡張として動いていた構造です。

失敗2と失敗3は、本記事の主題です。失敗4は、第3回(HITL)の主題になります。

つまり、Replit事件は4つのレイヤの設計欠陥が重ね合わさった結果として発火しました。第1回〜第3回の連載②前半は、この4つのレイヤを順に処方していく構造です。本記事はそのうち2つ——削除権限の分離、開発本番分離——に踏み込みます。

7. 3つの危険動作カテゴリと、その分離

連載①第5回で挙げた共通設計欠陥①「権限が広すぎる」を、具体的に3つの危険動作カテゴリに分解します。

このカテゴリ分けは、実装の出発点として極めて重要です。「最小権限を絞れ」という抽象論を、「これら3カテゴリだけは絶対に分離せよ」という具体論に翻訳することで、難しさ①(必要権限の事前確定不能)を回避できます。「全権限を事前に列挙する」必要はない。「絶対に他と混ぜてはいけない権限」を3つだけ特定すればいい、という設計判断です。

なお、この「削除・外部送信・金融」という3分類は、本記事が実装の出発点として整理したものであり、業界に同名のフレームワークがあるわけではありません。ただし、OWASP Top 10 for LLM Applications 2025のLLM06「Excessive Agency」が定義する「過剰な機能性・過剰な権限・過剰な自律性」という根本原因の整理や、NIST AI RMFの権限管理原則と概念的に整合しており、これらのフレームワークを実装単位に降ろした応用と位置づけられます。

カテゴリA:削除(Destructive)

該当アクション

  • DROP TABLE、TRUNCATE、DELETE FROM(フィルタなしまたは広範)
  • ファイル・ディレクトリの削除(rm、unlink)
  • リポジトリ削除、ブランチ強制削除(push --force、branch -D)
  • クラウドリソース削除(terraform destroy、リソース削除API)
  • バックアップの削除・スナップショットの破棄

特徴
これらは取り消し不能です。取り消し可能な操作(UPDATE、INSERT)と決定的に違います。Replit事件で1,206名・1,196社のデータが消えたのは、この削除権限がエージェントに付いていたからです。

カテゴリB:外部送信(Exfiltration-Capable)

該当アクション

  • 外部API呼び出し(curl、fetch、HTTPクライアント)
  • メール送信、Slack・Teams等のメッセージ送信
  • Webhook送信
  • 外部DBへの書き込み・外部ストレージへのアップロード
  • ネットワーク経由のファイル転送(scp、rsync)

特徴
これらは情報を組織の境界外に持ち出す経路です。AIエージェントが意図せず(あるいはプロンプトインジェクションで操作されて)機密情報を外部に送信するとき、必ずこのカテゴリのアクションが使われます。連載①第2回のMoltbookで、エージェント間DMから他社APIキーが流出した経路も、本質的にこのカテゴリの問題です。

カテゴリC:金融・実世界アクション(Real-World Impact)

該当アクション

  • 決済API呼び出し(Stripe charge、PayPal payment)
  • 金融トランザクション実行
  • 外部サービスの契約・解約
  • DNSレコード変更、ドメイン購入
  • 物理デバイス制御(IoT、産業制御)

特徴
これらはデジタル世界を超えた影響を持ちます。誤発火したときの被害は、データ消失や情報漏洩を超えて、金銭的損害・契約上の損害・物理的損害に及びます。

3カテゴリ分離の実装

これら3カテゴリを、1つのエージェントに混在させない。これが本記事の中核処方です。

flowchart LR A[古典的な統合エージェント<br/>━━━━━━<br/>1つのエージェントが<br/>読み・書き・削除・<br/>外部送信・金融すべてを保有] --> X[Replit型の事故が起こりうる状態] A -->|分離設計| B[読み取りエージェント<br/>SELECT・GET<br/>権限:読み取りのみ] A -->|分離設計| C[書き込みエージェント<br/>INSERT・UPDATE<br/>権限:書き込みのみ] A -->|分離設計| D[削除エージェント<br/>カテゴリA<br/>権限:削除のみ<br/>+ HITL承認必須] A -->|分離設計| E[外部送信エージェント<br/>カテゴリB<br/>権限:外部APIのみ<br/>+ 送信先ホワイトリスト] A -->|分離設計| F[金融エージェント<br/>カテゴリC<br/>権限:決済APIのみ<br/>+ HITL承認必須<br/>+ 上限金額] style A fill:#fa3 style X fill:#c00,color:#fff style B fill:#3a7 style C fill:#3a7 style D fill:#3af style E fill:#3af style F fill:#3af

たとえば「経理データ分析エージェント」は、読み取り専用にする。集計結果をメールで送る業務がある場合、それは別の「経理レポート送信エージェント」として実装し、外部送信権限のみを持たせる。両者は別のエージェントID、別の認証情報で動く。万が一、分析エージェントがプロンプトインジェクションで操作されても、機密データを外部に送信する経路を持っていない。送信エージェントが操作されても、読めるデータは事前に渡された集計結果だけで、生データへのアクセスは持っていない。

これは、難しさ②(学習データに基づく経路探索)への対処でもあります。ツール組み合わせの経路を完全に予測することはできないが、危険な3カテゴリを物理的に分離しておけば、組み合わせ経路が3カテゴリをまたぐことは原理的にできなくなる

実装の単位は、組織の規模・成熟度に応じて選びます。

  • 小規模:1つのコードベース内で、別のサービスアカウント・別のOAuthクライアントを使い分ける
  • 中規模:3カテゴリそれぞれを別のマイクロサービス・別のコンテナとして起動し、ネットワーク境界で分離する
  • 大規模:別のVPC・別のクラウドアカウントに分離し、IAMロール・ネットワークACLで強制する

最小限の実装でも、まずは「削除権限を持つエージェント」を業務の通常フローから分離するだけで、Replit型の事故の大半は防げます。

8. 開発DBと本番DBの分離 ― 動的シークレット注入

3カテゴリ分離と並んで、Replit事件が示した教訓のもう一つが開発環境と本番環境の分離です。

Replit事件で4,000件の架空ユーザーが本番DBに混入したのは、エージェントから見て「開発DB」と「本番DB」が区別できなかったからでした。エージェントは「動作確認のためのダミーデータが必要だ」と学習データから判断し、書き込み先のDBに対してINSERTを実行した。書き込み先が本番DBだったのは、たまたまでした。

これに対する素朴な対策は、「環境変数で切り替える」です。DATABASE_URLを本番用と開発用で切り替える。多くの組織がこの実装を取っています。

しかし、これでは不十分です。エージェントが両方の認証情報を同時に見える状態にあると、誤った参照や混入が起きるからです。たとえば.env.production.env.developmentが同じディレクトリにある状態で、エージェントが「動作確認のためにテストデータを投入する」というタスクを与えられたとき、エージェントは確率分布的にどちらのファイルを参照するか分かりません。

正しい設計は、動的シークレット注入です。なお「動的シークレット注入(dynamic secret injection)」は本記事の便宜的表現で、業界の公式用語としてはHashiCorp Vaultの「Dynamic Secrets」機能や、クラウドベンダーの「短命認証情報の動的発行」が対応する考え方です。

flowchart TB A[エージェントの起動要求] --> B{実行環境の判定} B -->|開発環境| C[Vault / Secrets Manager<br/>開発用認証情報のみを<br/>動的に発行] B -->|本番環境| D[Vault / Secrets Manager<br/>本番用認証情報のみを<br/>動的に発行] C --> E[エージェント実行<br/>開発DBにのみ接続可能<br/>本番DBの認証情報を持たない] D --> F[エージェント実行<br/>本番DBにのみ接続可能<br/>承認済みの厳格スコープ] E --> G[タスク完了] F --> G G --> H[認証情報を即座に破棄<br/>短命トークン] style C fill:#3a7 style D fill:#3af style H fill:#3af

動的シークレット注入の本質は、エージェントが現在のタスクの実行環境のものだけしか認証情報を見えないことです。HashiCorp Vault Dynamic SecretsAWS Secrets ManagerGCP Secret Manager + Workload Identity FederationAzure Key Vault——これらのツールは、そのために設計されています。

具体的な実装パターン:

  1. エージェントは、自分自身の認証情報を持たない(または起動時の最小限のIDトークンだけ)
  2. タスク開始時に、IDトークンを使ってSecrets Managerから「このタスクに必要な認証情報」を動的に取得する
  3. 認証情報は短命(数分〜数時間で失効)で、特定のリソースにスコープされている
  4. タスク完了時に、認証情報は破棄される
  5. 次回のタスクは、また動的に取得する

これを実装すると、Replit型の事故は構造的に防がれます。なぜなら、開発タスク用に起動されたエージェントは、本番DBの認証情報をそもそも持っていないからです。学習データの統計が「DBが空だから再構築しよう」と判断しても、本番DBにアクセスできないため、本番には影響しません。

これは、難しさ③(過剰権限が顕在化しない)への構造的対処でもあります。永続的な認証情報をエージェントに与えない設計にすれば、「使われていない過剰権限」がそもそも存在しなくなります。

9. エージェント職務記述書のテンプレート

3カテゴリ分離と動的シークレット注入は、技術的な処方です。これを組織の運用に乗せるためには、エージェント1つひとつに対して職務記述書を書く必要があります。

第1回で扱った「エージェントID発行」が、社員でいう入社手続きだとすれば、本節の職務記述書は配属時の業務分掌書にあたります。エージェントが何をするか、何をしないかを、人間が読める形式で明文化します。

flowchart LR A[エージェント職務記述書] --> B[基本情報] A --> C[業務スコープ] A --> D[権限定義] A --> E[禁止事項] A --> F[例外時フロー] A --> G[監査要件] A --> H[ライフサイクル] B --> B1[エージェント名・ID<br/>責任者・所属] C --> C1[業務目的・対象データ・<br/>呼び出し元] D --> D1[許可リソース<br/>許可アクション<br/>3カテゴリ分類] E --> E1[明示的な禁止リスト<br/>カテゴリA/B/C該当時の扱い] F --> F1[権限超過時の承認フロー<br/>第3回HITLへ接続] G --> G1[ログ要件・保管期間<br/>異常検知ベースライン] H --> H1[発行日・更新条件<br/>取消条件・退役手順] style A fill:#3af

最小限のテンプレートは、たとえばこうです。

YAML
agent_id: agent-finance-readonly-001
agent_name: "経理データ分析エージェント"
owner: yamashita.taro@example.com
department: 経理部
created: 2026-05-04

scope:
  purpose: "経理データの集計・サマリー作成"
  target_data: "会計DB(read-only接続)"
  invoked_by: "経理担当者からのSlackコマンド"

permissions:
  allowed_resources:
    - "db.finance.* (SELECT only)"
    - "internal-api.summarize (call)"
  allowed_actions:
    - SELECT
    - aggregate functions
  category_classification:
    A_destructive: NONE
    B_exfiltration: NONE
    C_real_world: NONE

prohibitions:
  - "他DBへの接続"
  - "外部APIへのアクセス"
  - "ファイルシステムへの書き込み"
  - "DELETE / UPDATE / INSERT文"

exceptions:
  if_permission_needed:
    - "新規DBへのアクセス要求 → 責任者承認 → IT審査"
    - "本記事第3回で扱うHITLフローに接続"

audit:
  log_retention: "1年"
  baseline:
    - "1日あたりクエリ数: 50-200"
    - "1クエリあたり結果行数: <10,000"
  alert_on_deviation: true

lifecycle:
  review_cycle: "四半期"
  revoke_conditions:
    - "30日間未使用"
    - "責任者の異動・退職"
    - "業務スコープの変更"

このテンプレートには、本記事で扱った設計判断がすべて埋め込まれています。

  • 3カテゴリ分類(permissions.category_classification):このエージェントは A・B・Cいずれにも該当しない読み取り専用、と明示。難しさ②(経路探索)への対処
  • 明示的な禁止リスト(prohibitions):ホワイトリストだけでなくブラックリストも書く。学習データの典型パターンが想定されない経路を作るのを抑制
  • 異常検知ベースライン(audit.baseline):第1回 Step 4「振る舞いベースライン化」と接続。難しさ③(顕在化しない過剰権限)への対処
  • 例外時フロー(exceptions):第3回(HITL)への接続点
  • ライフサイクル(lifecycle):四半期レビューで難しさ①(事前確定不能)に対処。実運用後の振る舞いを観察して、権限を絞り直す

実装の出発点として、組織が持つ全エージェントに対して、この粒度の職務記述書を書くのは負担が大きいかもしれません。優先順位の付け方は、シンプルです。

  1. 本番環境にアクセスするエージェントから書く
  2. 3カテゴリ(削除・外部送信・金融)のいずれかに該当するエージェントを最優先
  3. 個人開発者の人間IDに紐づいて動いているエージェントを次に
  4. 上記を満たさないエージェントは、優先度を下げる

この優先順位は、難しさ④(市場インセンティブとの衝突)への現実的な対処でもあります。「全エージェントを完璧に整備する」ではなく、事故が起きたら甚大な影響があるエージェントから順に整備する。これなら、組織の中で実装するインセンティブが立ち上がります。

10. 第3回(HITL)への接続 ― 「絞った権限の中で起こる事故」

ここまでの処方を実装すると、Moltbook型・Lovable型・Replit型の事故の大半は防げます。3カテゴリの分離が削除事故を防ぎ、動的シークレット注入が環境混入を防ぎ、職務記述書が運用の規律を作ります。

ただし、最小権限原則を厳密に適用しても、その権限の内側で予期しない動作が起こりうるという事実は残ります。

たとえば「読み取り専用」と思っていたエージェントが、SELECTクエリで巨大なデータを引き出して、許可された外部APIに送信する経路を作るかもしれません。SELECT自体は許可されている。外部API呼び出しも、業務上必要と判断されて許可されている。それでも、両者の組み合わせで「機密データの外部流出」という結果が発火することがあります。

3カテゴリを分離しても、カテゴリBに該当するエージェントの中で、想定されない外部送信が起きる可能性は残ります。最小権限原則は、権限の総量を絞ることで事故の規模を抑える設計ですが、絞った権限の内側で起こる事故までは防げません。

ここで必要になるのが、第3層の設計——「このアクションだけは、人間の承認を経由する」という仕組みです。

これが、第3回(ヒューマン・イン・ザ・ループの設計パターン)の主題になります。

第3回では、以下を扱います。

第1回(主体性)→ 第2回(権限スコープ)→ 第3回(人間承認)という3層構造が完成すると、AIエージェントの権限設計は、ようやく実用的なレベルに到達します。

まとめ

最小権限原則は、IT統制において半世紀の歴史を持つ古典原則です。しかし、AIエージェントに素直に当てはめようとすると、4つの構造的難しさによって空転します——必要権限が事前に確定しない、学習データに基づく経路探索が想定されないツール組み合わせを生む、過剰権限がエラーとして顕在化しない、市場インセンティブが「絞ること」を処罰する。

この4つの難しさは、最小権限原則を捨てる理由ではなく、素直な拡張ではなく、AIエージェント向けの実装翻訳が必要だ、という診断です。

本記事が提示した処方は、3つの実装層から成ります。

第1層:3つの危険動作カテゴリの分離
削除(Destructive)、外部送信(Exfiltration-Capable)、金融・実世界アクション(Real-World Impact)を、1つのエージェントに混在させない。読み取りエージェント・書き込みエージェント・削除エージェント・送信エージェント・金融エージェントを、別のIDと別の認証情報で動かす。「全権限を事前に列挙する」のではなく、「絶対に混ぜてはいけない3カテゴリだけ特定する」設計判断。

第2層:動的シークレット注入による開発本番分離
エージェントが永続的な認証情報を持たない。タスク開始時に、現在の実行環境に対応する認証情報のみを、Secrets Managerから動的に取得する。短命トークンで、タスク完了時に破棄される。Replit事件で発火した「開発タスクが本番DBを破壊する」構造を、原理的に不可能にする。

第3層:エージェント職務記述書
組織が運用する全エージェントに対して、業務スコープ・権限定義・禁止事項・例外時フロー・監査要件・ライフサイクルを明文化する。優先順位は「本番環境アクセス × 3カテゴリ該当 × 人間ID共有」のリスクスコアで付ける。完璧な整備を目指すのではなく、事故が起きたら甚大な影響があるエージェントから順に整備する。

これら3層は、第1回で確立した「エージェントの主体性整備」を前提にしています。エージェントIDが発行されていない組織で、本記事の処方を実装することはできません。第1回(主体性)→ 第2回(権限スコープ)の積み重ねが、ここで意味を持ちます。

ただし、最小権限を厳密に絞っても、絞った権限の内側で予期しない動作が起こりうる、という事実は残ります。次回(第3回)は、この最後のレイヤ——人間承認ゲートの設計パターン(ヒューマン・イン・ザ・ループ)——に踏み込みます。

連載①で見た事件群は、すべて「権限が広すぎた」ことが第一の原因でした。本記事の処方を実装すれば、その第一の原因は構造的に対処できます。事故の規模は、確実に小さくなります。

設計は、奇跡を起こす技ではありません。取り消し不能な行為と、取り消し可能な行為を分ける。境界の外と内を分ける。実行する者と承認する者を分ける。これら古典的な分離原則を、AIエージェントという新しい主体に対して、丁寧に翻訳していくこと——これが連載②が積み上げていく、現実的な防衛線です。

参考情報
山下 太郎

山下 太郎

代表取締役 / CEO

2000年、Webデザイナーとしてこの世界に飛び込み、フリーランスを経て2007年に株式会社アンタイプを創業。AI時代の到来とともに、効率だけを追うAI活用に違和感を覚えながら、それでも最前線でツールを使い続ける。企業のWebとコミュニケーションを設計する仕事を通じて、「人間らしさとは何か」を問い直す視点を発信し続けている。

View Profile arrow_outward

Related

あわせて読みたい