AIエージェントとは、運用上は認証情報を保持したプロセスです。誰かがサービスアカウント、APIキー、IAMロールをそのエージェントに割り当て、仕事をこなせるようにします。そしてその瞬間から、エージェントはそれらの認証情報が到達できるすべてに到達できるようになります。職務記述には「課金データを毎晩エクスポートする」と書かれていました。認証情報には「本番データベース、オブジェクトストア、そしてキューの読み取りと書き込み」と書かれていました。この両者を照合した人は誰もいませんでした。数か月後、チームの誰も、本来なら自明であるべき問いに答えられなくなります。このエージェントは実際に何に到達でき、実際に何に触れているのか?
このギャップは仮定の話ではありません。独立した業界調査(CSA/Token)によると、約82%の組織が自分たちの把握していないAIエージェントを稼働させており、それらのリアルタイムインベントリを維持している組織はわずか約21%にすぎません。見えないものは統治できません。そして現在、ほとんどの環境はエージェントそのものすら見えていないのが実情です——ましてや、各エージェントと到達可能なリソースを結ぶエッジなど、なおさらです。
日常的に混同される、3つの異なる問い
「このエージェントは何に到達できるのか」という問いに答えるのが難しいのは、それが3つの別々の問いを1つに圧縮しているからです。これらを区別し続けることが、すべての肝です。
- 保持(Held) — エージェントが所持している認証情報。トークン、キー、ロールバインディングなど。これはアイデンティティに関する事実です。つまり、エージェントがどの扉の鍵を持っているか、ということです。
- 許可(Permitted) — それらの認証情報がポリシー上許可されている内容。IAMの付与、データベースロール、ネットワークルールなど。これはポリシーに関する事実であり、ほぼ常に誰の記憶よりも広範です。なぜなら、付与された権限は積み重なっていく一方で、誰もそれを取り消さないからです。
- 観測(Observed) — エージェントが実際に行っているところを目撃された内容。どのリソースに到達したか、そして各アクセスが読み取りだったか書き込みだったか。これは挙動に関する事実であり、収集するまではどこにも存在しません。
ほとんどのセキュリティツールは許可の段階で止まります。IAMを読み込み、エージェントが課金エクスポート用バケットへ書き込みできると教えてくれます。それは必要ではありますが不十分です。なぜなら「できる」とは数千もの潜在的な能力の集合であり、人間が数千もの「かもしれない」をトリアージすることはできないからです。状況を変えるのは、観測を許可の隣に並べ、その差分を見ることです。
アクセスマップ
アクセスマップとは、それらのエッジのグラフです。発見されたすべてのエージェントについて、到達可能な各リソースへのエッジを描き、そのエッジ上で実際に観測された内容を注釈として付与します。重要なのはエッジという単位であり、エッジ上で最も重要な注釈が、読み取り/書き込みの区別です。
R(読み取り) は、エージェントがデータを変更せずに取得したことを意味します——SELECT、GET、ファイルの読み取りなどです。RW(読み取り/書き込み) は、状態を変更したことを意味します——INSERT/UPDATE/DELETE、オブジェクトストレージへの PUT、スキーマのマイグレーションなどです。この2つのブラストレイディウス(影響範囲)は比較になりません。機密テーブルへの読み取りエッジは、情報露出の問題です。書き込みエッジ——とりわけ意図しないもの——は、完全性とインシデントの問題です。両者を同じ「アクセス」として扱うことこそ、チームが本当に重要な検出結果を見逃す原因です。
マップを構築すると、1つのエージェントの行は次のように見えます。
| Agent | Resource | Permitted | Observed | Confidence |
|---|---|---|---|---|
| data-export-job | prod-postgres | RW | RW | attributed |
| data-export-job | s3://billing-exports | RW | R | attributed |
| data-export-job | internal-metrics-api | R | — | approximate |
最初の行を見てください。このエクスポートジョブは、prod-postgres から読み取り、その結果を s3://billing-exports へ書き込むことが意図されていました。ソースを読み取り、宛先へ書き込む、というわけです。ところが、このジョブに渡された認証情報はデータベースに対する RW を付与しており、コレクターはこのジョブが prod-postgres へ書き込んでいるところを観測しました——誰もレビューも意図もしておらず、現時点で誰も説明できない、本番の正本システム(system of record)に対する変更です。許可(Permitted)列は、これがずっと許可されていたと静かに告げていました。これはインシデントの種であり、目の前にはっきりと存在しているのに、観測(Observed)列がなければ、それを警告として上げる手立ては何もありません。
許可マイナス観測はドリフトに等しい
最も特徴的な出力は、この差分です。最小権限のドリフト(least-privilege drift) とは、一方の列からもう一方を差し引いたときに得られるものであり、それは双方向に作用します。
- 許可されているが一度も観測されていない — エージェントは
internal-metrics-apiに到達できるにもかかわらず、観測ウィンドウ全体を通じて一度も到達しませんでした。これはデッドスコープ(不要な権限)です。安全に取り消しを提案できる付与権限であり、挙動には一切触れずにアタックサーフェスを縮小できます。 - レビューされた範囲を超えて観測された — 誰も承認していなかった
prod-postgresへの書き込みです。これが信号の強い検出結果です。つまり、もしプロビジョニング時に誰かに尋ねていれば承認されなかったであろう操作が、実際に起きているということです。
2つ目のカテゴリこそが見出しになるべきリスクであり、誠実なプロダクトはそれを決して捏造しません。観測されたすべてのエッジには信頼度(confidence level) が付随します——attributed(帰属確定)は、その操作が裏付けとなる信号とともに特定のエージェントアイデンティティに結び付けられている場合、approximate(近似)は証拠がより弱い場合です。推測を確実なものへとすり替えるのではなく、その差を明示します。自信を持って裏付けられない検出結果は、検出結果がないことよりも悪いのです。
パッシブに発見し、エージェントごとに帰属させる
これを単なるもう一つのダッシュボードではなく信頼できるものにしているのは、2つの設計上の選択です。
第一に、発見はパッシブです。コレクターは観測します——ログ、OpenTelemetry のトレース、PostgreSQL の pgAudit のようなデータベース監査ストリーム、そしてグラウンドトゥルース(真の値)を裏付けるためのカーネルレベルでの eBPF——そして、エージェントのデータパス上には居座りません。必須のプロキシは存在しません。コレクターが故障しても、エージェントは動き続けます。劣化するのは可観測性であって、本番環境ではありません。クリティカルなインフラの統治を本懐とするシステムにとって、この非対称性こそが設計思想です——ダウンサイドは小さく、シグナルは大きく。
第二に、すべての操作は、共有サービスアカウントではなく特定のエージェントアイデンティティに帰属させられます。これは、「エクスポートロールが 02:14 に prod-postgres へ書き込んだ」と告げる監査台帳と、どのエージェントが、誰のオーナーシップのもとで、どの意図されたスコープに対して行ったのかを告げる台帳との違いです。エージェントごとのアイデンティティは、最小権限が何らかの意味を持つための前提条件です——それがなければ、操作は目にできても、責任を負うべきオーナーへとたどり着くことは決してできません。
保存されるのは、エッジと読み取り/書き込みの事実だけです。マップが記録するのは関係性です——どのエージェントがどのリソースに対して、R なのか RW なのか——であって、ペイロードでも、読み取られた行でも、シークレットでもありません。シークレットやPIIを含む可能性のある入力は、何かが書き込まれる前にレダクション(編集除去)され、シークレットスキャンが行われます。このグラフは、まさにアクセスマップであるがゆえに機微であり、だからこそ統治を可能にする最小限のものだけを保持し、それ以上は何も持たないように作られています。
エージェント自身のエコシステムからのシグナルは役立ちますが、それ単体で信頼されることはありません。MCP サーバーは readOnlyHint のようなアノテーションを通じて、あるツールが読み取り専用であると表明するかもしれません。しかし MCP の仕様によれば、それらのヒントは信頼できない(untrusted) ものであり、必ず裏付けを取るべきであって、決して盲信してはなりません。読み取り専用だと主張しながら実際には書き込んだツールを捕捉するのは、カーネルレベルのビューです。
ひとたびマップが存在すれば、次のステップは強制(enforcement)です。エクスポートジョブをデータベースに対して読み取り専用にピン留めし、書き込みを拒否し、単にログを取るのではなくアラートを発する——インシデント後に再構成するのではなく、アクセス時点で適用されるポリシーです。
agent "data-export-job" {
resource "prod-postgres" {
access = "read" # intended scope: read source only
deny = ["write", "ddl"]
}
resource "s3://billing-exports" {
access = "read-write" # intended scope: write destination
}
on_violation {
action = "block"
alert = "secops"
}
}
マップは、あなたが本来書くべきだったポリシーを教えてくれます。なぜなら、エージェントが実際に必要としたただ一つのアクセスと、一度も使わなかった十数個のアクセスを示してくれるからです。これこそが、最小権限を推測することと、グラウンドトゥルースから導き出すことの違いです。
もしこれが、今あなたの環境では答えられない問いであるなら——各エージェントは何に到達でき、実際に何に触れているのか——それこそまさにアクセスマップの存在意義です。プロダクト概要では、発見と「許可 対 観測」の差分について解説しています。アーキテクチャでは、パッシブな収集、エージェントごとのアイデンティティ、監査台帳が、あなたのエージェントのデータパス上に決して居座ることなく、どのように噛み合うのかを取り上げています。