「AIエージェントに管理者権限を渡してしまった」──この一文でヒヤッとする方は、この記事を読んでいただく価値があります。
AIエージェントは人間のユーザーと同様に、APIを叩き、データベースを読み書きし、外部サービスを呼び出します。にもかかわらず、多くのチームがエージェントに過剰な権限を付与したまま本番に出しています。Palo Alto NetworksがAWS BedrockエージェントのIAMロールを調査した結果、デフォルト設定では「他エージェントのメモリ読み取り・ソースコード外部送信・任意のコードインタープリター起動」が可能だったと2026年に報告しています。
この記事では、AWS IAM・GCP Workload Identity・Azure Managed Identityを使ったAIエージェントの最小権限設計を、コピペ可能なポリシー例つきで解説します。
まず5分で試せる:最小権限チェックリスト
理論より先に、今すぐ確認できる項目を挙げます。
# AWSの場合:現在のエージェントIAMロールの権限を確認
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
aws iam get-role-policy \
--role-name YourAgentRoleName \
--policy-name YourPolicyName \
--query 'PolicyDocument.Statement[].Action' \
--output json
# 「"*"」が含まれていたら最小権限未達。即座に見直しが必要
# 出力例(危険): ["*"]
# 出力例(適切): ["bedrock:InvokeModel", "s3:GetObject"]
ワイルドカード権限(`*`)がついたIAMロールは、エージェントが侵害された瞬間に攻撃者が全AWSリソースにアクセスできる状態になります。AIエージェントの基本設計についてはAIエージェント構築完全ガイドでも触れていますが、権限設計は最も軽視されやすい要素の一つです。
最小権限とは何か、AIエージェントで何が違うのか
最小権限原則(Principle of Least Privilege)自体は古い概念ですが、AIエージェントには3つの固有のリスクがあります。
- プロンプトインジェクション: 悪意あるユーザー入力がエージェントに意図しないツール呼び出しをさせる。権限が広いと被害が大きくなる
- マルチエージェント伝播: 1つの侵害されたエージェントが他エージェントのAPIキーやメモリにアクセスできる(Palo Alto Networks 2026年報告)
- 長期実行タスク: 人間のセッションと異なり、エージェントは長時間稼働し大量の操作を実行する
NISTs 2026年2月の概念論文も「AIエージェントは既知・信頼済み・適切にガバナンスされた存在として扱われなければならない」と明示しています。
1. AWS IAM:ベドロックエージェントの最小権限設計
AWSではIAMポリシーで操作単位・リソース単位の制御が可能です。エージェントごとに専用の最小権限ロールを作ることが基本原則です。
// aws_agent_minimal_policy.json
// 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockInvokeSpecificModel",
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": [
"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0"
]
},
{
"Sid": "S3ReadOnlySpecificBucket",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-agent-knowledge-base",
"arn:aws:s3:::my-agent-knowledge-base/*"
]
},
{
"Sid": "DenyIAMOperations",
"Effect": "Deny",
"Action": ["iam:*", "organizations:*"],
"Resource": "*"
}
]
}
IAMロールの信頼ポリシー(Trust Policy)では `aws:SourceArn` を使って、特定のエージェントからしか引き受けられないよう制限します。
// trust_policy.json - 特定のBedrockエージェントだけがこのロールを引き受けられる
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "bedrock.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": "123456789012"},
"ArnLike": {
"aws:SourceArn": "arn:aws:bedrock:us-east-1:123456789012:agent/AGENT_ID"
}
}
}]
}
ポイント: `aws:SourceArn` の条件がないと、同じAWSアカウント内の他のサービスがこのロールを借用できてしまいます。エージェントAのロールをエージェントBが引き受けられるようなクロスエージェント権限昇格を防ぐために必須です。
2. GCP Workload Identity:エージェントの認証を静的キー不要にする
GCPでは、サービスアカウントキーをファイルとして持つ代わりに、Workload Identity Federationで動的に短期トークンを取得できます。これによりキーのローテーション忘れや漏洩リスクが大幅に減ります。
# GCP Workload Identity設定(KubernetesにデプロイされたAIエージェント用)
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
# 1. サービスアカウントを作成(1エージェント1サービスアカウント)
gcloud iam service-accounts create ai-agent-reader \
--display-name="AI Agent Reader SA" \
--project=my-project
# 2. 必要な権限だけを付与(ここでは BigQuery 読み取りのみ)
gcloud projects add-iam-policy-binding my-project \
--member="serviceAccount:ai-agent-reader@my-project.iam.gserviceaccount.com" \
--role="roles/bigquery.dataViewer"
# 3. Kubernetes ServiceAccountとバインド(キーファイル不要!)
gcloud iam service-accounts add-iam-policy-binding \
ai-agent-reader@my-project.iam.gserviceaccount.com \
--role="roles/iam.workloadIdentityUser" \
--member="serviceAccount:my-project.svc.id.goog[default/ai-agent-sa]"
# Workload Identityを使ったGCPクライアント認証(Python)
# キーファイル不要で自動的に認証される
# pip install google-cloud-bigquery google-auth
from google.cloud import bigquery
from google.auth import default as google_auth_default
# Application Default Credentials で自動認証(環境変数やWorkload Identityを自動検出)
creds, project = google_auth_default(
scopes=["https://www.googleapis.com/auth/bigquery.readonly"]
)
client = bigquery.Client(credentials=creds, project="my-project")
query = "SELECT * FROM my_dataset.my_table LIMIT 100"
results = client.query(query).result()
for row in results:
print(row)
ポイント: `google.auth.default()` はWorker Identity、サービスアカウントキーファイル、ユーザー認証情報を自動で検出します。Kubernetes環境ではWorker Identityが最優先で使われ、静的キーファイルは不要になります。
3. Azure Managed Identity:エージェントにシークレット不要の認証
AzureのManaged Identityは、GCPのWorkload Identityに相当する仕組みです。AzureリソースにデプロイされたエージェントはMSI(Managed Service Identity)を通じて、ストレージやKey Vaultに認証情報なしでアクセスできます。
# Azure CLIでManaged Identityを有効化してRBAC割り当て
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
# Container Apps にシステム割り当てManaged Identityを付与
az containerapp update \
--name my-ai-agent \
--resource-group my-rg \
--system-assigned
# エージェントのManaged IdentityのプリンシパルIDを取得
PRINCIPAL_ID=$(az containerapp show \
--name my-ai-agent \
--resource-group my-rg \
--query identity.principalId -o tsv)
# ストレージアカウントの読み取り権限のみを付与(Storage Blob Data Readerロール)
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Storage Blob Data Reader" \
--scope "/subscriptions/{sub}/resourceGroups/my-rg/providers/Microsoft.Storage/storageAccounts/myagentstorage"
# Azure SDKでManaged Identity認証(Python)
# pip install azure-identity azure-storage-blob
from azure.identity import ManagedIdentityCredential
from azure.storage.blob import BlobServiceClient
# Managed Identityで自動認証(接続文字列やシークレット不要)
credential = ManagedIdentityCredential()
blob_client = BlobServiceClient(
account_url="https://myagentstorage.blob.core.windows.net",
credential=credential
)
container = blob_client.get_container_client("knowledge-base")
for blob in container.list_blobs():
print(blob.name)
ポイント: `ManagedIdentityCredential()` は Azure 環境では自動的にMSIエンドポイントからトークンを取得します。ローカル開発では `DefaultAzureCredential()` を使うと Azure CLI 認証にフォールバックするため、コードの変更なしに開発・本番で動作します。
クラウド横断:最小権限設計の比較表
| 比較軸 | AWS IAM | GCP Workload Identity | Azure Managed Identity |
|---|---|---|---|
| 静的キー不要 | IAM Rolesで可能(STS) | Workload Identity Federation | Managed Identity(最もシンプル) |
| リソース単位制御 | ARN指定で細粒度 | IAMバインディングでリソース指定 | RBACスコープで制御 |
| Kubernetes対応 | IRSA(IAM for SA) | Workload Identity Pool | AKS Workload Identity |
| クロスサービス防止 | aws:SourceArn条件 | サービスアカウントの分離 | スコープ付きロール割り当て |
| マルチクラウド | OIDC Federation | Workload Identity Pool | Federated Identity Credential |
【要注意】よくある設計ミスと回避策
失敗1:エージェント間で同一IAMロールを共有
❌ 複数のエージェントが同一のIAMロール・サービスアカウントを使い回す
⭕ 1エージェント = 1IAMロール / 1サービスアカウントを徹底する
なぜ危険か: 共有ロールは1エージェントが侵害されると、そのロールを使う全エージェントが侵害されるカスケード障害につながります。NISTs 2026年論文もエージェントごとの独立した認証を推奨しています。
失敗2:iam:PassRoleを広く許可
❌ IAMロールに `”Action”: “iam:PassRole”, “Resource”: “*”` を設定
⭕ `iam:PassRole` は必要最小限のARNに制限する
// 正しいiam:PassRole設定
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/specific-agent-role",
"Condition": {
"StringEquals": {
"iam:PassedToService": "bedrock.amazonaws.com"
}
}
}
失敗3:長期有効な静的APIキーを使い続ける
❌ .env ファイルにAWSアクセスキーIDとシークレットを直書き
⭕ IAM Role(AWS)・Workload Identity(GCP)・Managed Identity(Azure)を使って静的キーを排除
なぜ重要か: 静的キーはGitへの誤コミット・CI環境のログ漏洩・コンテナイメージへの混入など、漏洩経路が多すぎます。
参考・出典
- Cracks in the Bedrock: Agent God Mode(Palo Alto Networks Unit42) — paloaltonetworks.com(参照日: 2026-04-11)
- IAM policy examples for Amazon Bedrock Agents(AWS公式) — docs.aws.amazon.com(参照日: 2026-04-11)
- Workload Identity Federation(GCP公式) — cloud.google.com(参照日: 2026-04-11)
- Workload Identity and Access Management: The Definitive Guide — securityboulevard.com(参照日: 2026-04-11)
- AI Privilege Guardian(Token Security) — token.security(参照日: 2026-04-11)
まとめ:今日から始める3つのアクション
- 今日やること: 本番エージェントのIAMロールに `”*”` が含まれていないか確認する。含まれていたら最優先で最小権限ポリシーに置き換える
- 今週中: エージェントが実際に使うアクションを `aws cloudtrail`(AWS)・Cloud Audit Logs(GCP)・Activity Logs(Azure)でリストアップし、使っていないアクションを全て削除する
- 今月中: 全エージェントの静的APIキーをManaged Identity / Workload Identity / IAM Roleに移行し、`git-secrets` や `detect-secrets` でキーの漏洩チェックをCIに組み込む
あわせて読みたい:
- AIエージェント構築完全ガイド — セキュリティを含む設計全体の体系的な解説
- AIエージェントツール比較 — フレームワーク選定とセキュリティ考慮点
AIエージェントのセキュリティ設計・導入支援については、株式会社Uravation(お問い合わせ) にご相談ください。
この記事はAIgent Lab編集部がお届けしました。