コンテンツへスキップ

least-privilege

最小権限ドリフト: インシデント発生前に過剰権限のAIエージェントを検知する

著者 Olivares AI 1 分で読めます

最小権限は、セキュリティにおいて最も古く、最も信頼できる考え方の一つです。あるアイデンティティに対して、必要なアクセスだけを正確に与え、それ以上は与えない。そうすれば、いかなる侵害が起きてもその影響範囲は小さく保たれます。人間のアカウントや長命なサービスアカウントについては、このモデルはおおむね機能します。ロールはレビューされ、権限はスコープが定められ、アクセス認証は四半期ごとのサイクルで実施されます。

AIエージェントは、このモデルを静かに崩壊させます。エージェントには、認証情報、ツール、MCPサーバーへの接続が与えられ、その瞬間からその挙動は動的になります。どのリソースを読み、どれに書き込み、次にどのツールを呼び出すかを、実行時に自ら決定するのです。初日に書き下した権限付与は、上限を記述したものであって、エージェントが実際に何をするかを記述したものではありません。そしてエージェントは生産的であるがゆえに、その上限は寛大になりがちです。広範なデータベースロール、「念のため」の書き込みアクセス、半ダースものワークフローで共有されるサービスアカウント。その結果として生まれるのは、許可されたアクセスと実際に使われているアクセスが、毎日、静かに乖離していくエステートです。

独立した業界調査は、この死角の規模を捉えています。およそ82%の組織が、自分たちが把握していないAIエージェントが稼働していると報告している一方で、それらをリアルタイムにインベントリ管理している組織はわずか約21%にすぎません(CSA/Token Security、n=418)。可視化できないエステートに対して、最小権限を強制することはできません。

最小権限ドリフトを定義する

その対象を正確に名付けましょう。最小権限ドリフトとは、エージェントが許可されているアクセスと、観測されているアクセスとの間で広がっていくギャップのことです。 これには2つの失敗の方向があり、そのうち明白なのは一方だけです。

明白な方向は過少利用です。エージェントが、一度も書き込んだことのないテーブルに対して書き込みアクセスを保持している状態です。これは死んだ権限であり、何の利益もないまま抱え続けているリスクです。危険なのは、その逆方向のシグナルです。観測された集合に、許可された集合が意図的に付与したことのないものが含まれているとき、誰もレビューしていないアクションが発生していることになります。これまで読み取りしかしてこなかったバケットに突然書き込みを始めるエクスポートジョブ。ポリシーで一つのスキーマにスコープされていたはずなのに、別のスキーマへと手を伸ばすエージェント。これらは特殊な事例ではありません。粒度の粗い権限で配線されたエージェントの、ありふれた日常の質感そのものです。

これが難しい理由、そしてそれが人間ではなくエージェントに固有である理由は、その挙動が設定されたものではなく、生成されたものだという点にあります。過剰なアクセスを持つ人間は、たいていそれを行使しません。しかし過剰なアクセスを持つエージェントは、目の前のタスクを完了させるのに役立つことなら何でも行使します。それには、誰も予期していなかったパスも含まれます。実行ごとに変化する挙動に、静的なポリシーレビューが追いつくことはできません。

ドリフトをレビュー可能なシグナルに変える

ドリフトが危険なのは、それが見えない間だけです。仕事は、それを人間がレビューできるシグナルに変えることであり、そのためには2つのものが連携して機能する必要があります。エージェントが実際に何に触れているかの継続的な観測と、エージェントが何に触れることを許可されていたかの安定した記録です。

観測はリードファーストでなければなりません。ログ、OpenTelemetryトレース、eBPFカーネルシグナルから観測するコレクターは、エージェントのデータパスの外側に位置します。それはプロキシではなく、呼び出しをゲートすることもありません。そしてもし障害が起きても、安全な意味でフェイルオープンします。エージェントは動き続け、失われるのは可用性ではなく可視性です。この非対称性が重要です。本番環境を停止させかねないセキュリティコントロールは、チームがこっそり無効化してしまうコントロールだからです。とりわけeBPF層は、カーネルレベルのグラウンドトゥルースとして機能します。これはエージェントが回避できない部分であり、だからこそMCPツールアノテーション(readOnlyHintdestructiveHint)といったプロトコルレベルのヒントは、信頼されるのではなく、それと照合して裏付けられます。MCP仕様そのものが、これらのアノテーションは信頼できないと述べています。その照合を実体のあるものにするのが、カーネルシグナルなのです。

観測が生み出すのはアクセスマップです。各エージェントについて、どのリソースに到達したか、そしてそれが読み取り(R)だったのか、読み取り/書き込み(RW)だったのかを示します。このマップが保存するのはアクセスの関係性であり、ペイロードやシークレット、PIIではありません。興味深いのは、その差分です。

エージェントリソース許可観測ドリフト
data-export-jobprod-postgresRRなし
data-export-jobs3://billing-exportsRRWレビュー未済の書き込み
report-builderanalytics-dbR(未使用)死んだ権限

重要なのは真ん中の行です。ポリシーはエクスポートバケットに対して読み取りを付与しましたが、コレクターは書き込みを観測しました。この一行こそが、最小権限ドリフトが浮かび上がらせるべき最大のリスクです。誰もレビューしていない権限が行使されており、しかもそれが共有サービスアカウントではなく特定のエージェントに帰属させられています。エージェント単位のアイデンティティこそが、その帰属と監査をそもそも可能にするものだからです。

単にログを取るのではなく、アクセス時に強制する

検知は、ドリフトが起きたことを教えてくれます。ループを閉じるには、レビューされていない書き込みを、ログに記録されるパスではなく、拒否されるパスにしたいところです。そこで登場するのが、アクセス時に評価されるpolicy-as-codeです。ドリフトをフラグ付けしたのと同じ差分が、それを防止するルールになります。

エクスポートジョブを本番データベースに対して読み取り専用に固定し、書き込みを完全に拒否することを検討してみましょう。違反が黙って素通りするのではなく、ブロックしてアラートを上げるようにします。

agent "data-export-job" {
  # Read-only on the operational database. No writes, ever.
  access "prod-postgres" {
    mode  = "read"
    deny  = ["write", "delete", "ddl"]
  }

  # The export target the job is *supposed* to use.
  access "s3://billing-exports" {
    mode = "read"
  }

  on_violation {
    action = "block"        # deny the call at access time
    alert  = "security-oncall"
    audit  = "append"       # write to the tamper-evident ledger
  }
}

ビフォーとアフターを具体的にたどってみましょう。

ビフォー。 広範なロールを保持したエクスポートジョブが、s3://billing-exportsに対して書き込みを発行します。その動作を止めるものはありません。アクションは成功し、通常のトラフィックに紛れ込み、もし表面化するとしても、数日後にアクセスマップ上の異常として現れる程度です。許可されたものと観測されたものの間のギャップは広がり、残された唯一の痕跡は、誰も読まなかったログの一行です。

アフター。 同じ書き込みが到着します。ポリシーはアクセス時に評価され、readにスコープされたリソースに対するwriteを検知し、操作が着地する前に拒否を返します。違反は呼び出しをブロックし、オンコールローテーションにアラートを上げ、追記専用でハッシュチェーン化された監査台帳にエントリを追記します。レビューされていない書き込みが、レビューされていない変更になることは決してありません。ドリフトは、まさにその瞬間に、最小権限のパスへと変換されるのです。

これを誠実なものに保つ性質が2つあります。第一に、アクセスマップに対するあらゆる特権的な閲覧それ自体が監査されます。誰が何を見たか、ということです。なぜなら、このマップは機密性が高く、自分自身のオペレーターについて説明責任を果たせないセキュリティツールは信頼に値しないからです。第二に、根拠の種類が明示的に示されます。カーネルレベルの証拠によってエージェントに帰属させられたアクションは、近似的に推測されたものとは区別して表示されます。捏造された確実性に基づいて行動することを求められることは、決してありません。

まとめ

最小権限がAIエージェントに対して失敗したのではありません。失敗したのはレビューのサイクルです。権限は粒度が粗く、挙動は動的であり、四半期ごとの認証では、実行のたびに変化するアクセスサーフェスを追跡できません。解決策は、クリティカルパスにより重いプロキシを置くことではありません。許可された権限と観測された権限の差分を生み出す、継続的でリードファーストな観測。そして、修正された境界をアクセス時に強制するpolicy-as-code。これらによって、過剰権限のエージェントは、インシデントになるずっと前に、レビュー可能なシグナルとして捕捉されるのです。

コレクター、アクセスマップ、アクセス時の強制が、エージェントのデータパス上に置かれることなくどのように組み合わさるのかをご覧になりたい方は、アーキテクチャページで設計全体を解説しています。また製品ページでは、許可された権限と観測された権限のビューが、実際のエステート上でどのように見えるかをご覧になれます。

よくある質問

AIエージェントにおける最小権限ドリフトとは何ですか?

最小権限ドリフトとは、エージェントが「許可されていること」と「実際に行っていると観測されること」の間で広がり続けるギャップのことです。粒度の粗い権限付与と動的な挙動により、エージェントは誰も承認していないリソースに、誰かが気づくよりずっと前から触れ始める可能性があります。ドリフトはそのギャップが静かに蓄積していく現象であり、許可された集合と観測された集合を継続的に比較してはじめてレビュー可能になります。

本番環境を壊さずに過剰権限のエージェントを検知するにはどうすればよいですか?

傍受するのではなく、観測してください。リードファーストのコレクターは、エージェントのデータパス上に置かれるのではなく、ログ・OpenTelemetry・eBPFカーネルシグナルから読み取ります。そのため、コレクターの障害がエージェントをブロックすることは決してありません。この観測が「許可された権限と観測された権限の差分」を生み出します。そして強制は、アクセス時に評価されるpolicy-as-codeに置かれ、レビューされていない書き込みが拒否されるパスとアラートに変わります。

エージェントが到達できる範囲を可視化

Olivares AIは、お客様のAI環境のためのオープンなセルフホスト型プラットフォームです。ご自身のインフラ上に展開すれば、セキュリティチームやプラットフォームチームがこれまで求めてきたアクセスマップが手に入ります。