LLMアプリのためのIAM: 呼び出し元がモデルであるときの最小権限
呼び出し元がモデルであっても最小権限は変わらず適用される。各エージェントツールには、単一の広範な管理者クレデンシャルではなく、スコープされたIAMロールとセッションポリシーを与えること。

エージェントは完全には予測できない呼び出し元であり、まさにそれこそが最小権限を持つべき呼び出し元だ。新しいエージェントに対する直感的な反応は、反復開発中に「とにかく動く」ように広範なロールを与えることだ。その直感こそが、あらゆるバケットを読み取り、あらゆるテーブルを削除できるクレデンシャルを持つ、しかも攻撃者が影響を与えられるテキストによって動かされる言語モデルを生み出す結末につながる。最小権限は常にルールだった。非決定的な呼び出し元は、それを交渉の余地のないものにする。
発想の転換は、エージェントを自分のコードだと考えるのをやめ、自分の代わりに実行する半信頼のアクターだと考え始めることだ。あなたのコードはあなたが書いた通りに動く。エージェントはモデルが決めた通りに動き、そのモデルはあなたがコントロールできない入力に基づいて決めている。IAMの境界は「エージェントが変な選択をした」ことと「エージェントが管理者権限で変な選択をした」ことの間に立つものだ。
エージェント単位ではなくツール単位で1つのロール
よくあるアンチパターンは、エージェント全体に1つの実行ロールをアタッチし、どのツールが必要とする可能性があるすべての権限の和集合を持たせることだ。そのロールは今や、すべてのツールを合わせた被害範囲そのものになる。最も弱いツールに到達したプロンプトインジェクションは、最も強いツールの権限を継承してしまう。
権限はエージェントではなくツールにスコープする。lookup_orderツールの背後にあるLambdaには、1つのテーブルだけを読み取れて他には何もできないロールを与える。send_emailの背後にある関数には、1つの検証済みIDについてのみSESを呼び出せるロールを与える。どのツールも使わない権限は持たない。だから侵害されたツール呼び出しも、そのツールの1つの仕事しかできない。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "dynamodb:GetItem",
"Resource": "arn:aws:dynamodb:eu-west-1:111122223333:table/orders",
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": ["${aws:PrincipalTag/tenant}"]
}
}
}]
}これが注文検索ツールの権限のすべてだ。1つのテーブルから、1つのアイテムを読み取るだけで、しかも呼び出し元のテナントの行だけに限られる。インジェクションされた指示が到達できる先は他に何もない。
セッションポリシーで実行時にロールをさらに狭める
ツール単位のロールは最低ラインだ。マルチテナントシステムでは、権限を特定のリクエストにスコープしたい場合もある。セッションポリシーはそれを可能にする。バックエンドがツールのロールを引き受ける際、インラインポリシーを渡すことで、そのセッション1回限りのロールの権限と交差させる。これにより、テナントAのために動作するリクエストは、ロールが技術的にはテーブル全体に及んでいても、テナントBのデータには触れられない。
aws sts assume-role \
--role-arn arn:aws:iam::111122223333:role/order-lookup \
--role-session-name agent-tenant-a \
--policy '{"Version":"2012-10-17","Statement":[{
"Effect":"Allow","Action":"dynamodb:GetItem",
"Resource":"arn:aws:dynamodb:eu-west-1:111122223333:table/orders",
"Condition":{"ForAllValues:StringEquals":
{"dynamodb:LeadingKeys":["tenant-a"]}}}]}'実効的な権限はロールとセッションポリシーの交差であり、ツールが実際に持つクレデンシャルはこのリクエストに合わせて狭められる。セッションタグとロール上のテナント条件の組み合わせでも同じことを宣言的に達成できる。いずれにせよ、モデル駆動の呼び出しに渡されるクレデンシャルは、現在のタスクを完了するのに必要な最小の集合になる。
クレデンシャルの手前にあるポリシー
IAMはプリンシパルが何をできるかを決める。しかし、この特定のエージェントが、この特定のターンで、そもそもこのツールを呼び出すべきかどうかは決めない。その認可の問いには、AWS上に専用の答えが今や存在する。今月初めに一般提供が始まったAmazon Bedrock AgentCoreのPolicyは、自然言語で記述してCedarにコンパイルされるルールに照らして、各エージェントからツールへのリクエストを評価し、AgentCore Gatewayで呼び出しが進む前に強制する。これはIAMの置き換えではなく、その手前のレイヤーとして読むべきだ。ゲートウェイがそのツール呼び出しを許可するかを決め、厳格なIAMロールが、もし許可された場合にどれだけ小さな被害しか与えられないかを決める。
API呼び出しだけでなくロールの引き受けをログする
ツールがスコープされたロールを引き受けるため、CloudTrailはきれいな監査証跡を提供する。どのロールが、どのセッション名で、どのタスクのために引き受けられたか。role-session-nameをエージェントのターンとテナントに紐づく値に設定すれば、エージェントが正確に何を、誰の権限のもとで行ったかを再構築できる。エージェントが誤動作したとき、その証跡が、説明可能な限定的なインシデントと、説明不能な謎との差になる。
結論
最小権限は、呼び出し元が賢いからといって緩まない。むしろ引き締まる。なぜなら呼び出し元は非決定的で、信頼できない入力に影響されるからだ。各ツールに独自の狭いロールを与え、リクエストごとにセッションポリシーで交差させ、AgentCore Policyのような認可レイヤーを手前に置き、すべてのロール引き受けをログする。モデルが誤った判断をしたとき、そしてそれは必ず起きるが、その誤った判断を小さく留めるのはIAMだ。
次に読む
- Bedrock Guardrails Won't Save You From Prompt Injection。コンテンツフィルタリングが境界ではなく、IAMが境界である理由について。
IAMの深部とアカウントの堅牢化については、クラウドのフィールドノートに詳しい。AWSアカウントのセキュア化はercan.cloudにある。ハブはercanermis.com。
Ercan の他のサイト
同じ著者、別の領域のサイトが2つ。