AIエージェント入門

AIエージェント最小権限設計|AWS/GCP/Azure IAM実装ガイド

AIエージェント最小権限設計|AWS/GCP/Azure IAM実装ガイド

この記事の結論

AIエージェントへの過剰権限付与はセキュリティリスクの根本原因です。AWS IAM・GCP Workload Identity・Azure Managed Identityで最小権限を実装する実践ガイド。

「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. プロンプトインジェクション: 悪意あるユーザー入力がエージェントに意図しないツール呼び出しをさせる。権限が広いと被害が大きくなる
  2. マルチエージェント伝播: 1つの侵害されたエージェントが他エージェントのAPIキーやメモリにアクセスできる(Palo Alto Networks 2026年報告)
  3. 長期実行タスク: 人間のセッションと異なり、エージェントは長時間稼働し大量の操作を実行する

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環境のログ漏洩・コンテナイメージへの混入など、漏洩経路が多すぎます。

参考・出典

まとめ:今日から始める3つのアクション

  1. 今日やること: 本番エージェントのIAMロールに `”*”` が含まれていないか確認する。含まれていたら最優先で最小権限ポリシーに置き換える
  2. 今週中: エージェントが実際に使うアクションを `aws cloudtrail`(AWS)・Cloud Audit Logs(GCP)・Activity Logs(Azure)でリストアップし、使っていないアクションを全て削除する
  3. 今月中: 全エージェントの静的APIキーをManaged Identity / Workload Identity / IAM Roleに移行し、`git-secrets` や `detect-secrets` でキーの漏洩チェックをCIに組み込む

あわせて読みたい:


AIエージェントのセキュリティ設計・導入支援については、株式会社Uravation(お問い合わせ) にご相談ください。

この記事はAIgent Lab編集部がお届けしました。

Need help moving from reading to rollout?

この記事を読んで導入イメージが固まってきた方へ

Uravationでは、AIエージェントの要件整理、PoC設計、社内導入、研修まで一気通貫で支援しています。

この記事をシェア

X Facebook LINE

※ 本記事の情報は2026年4月時点のものです。サービスの料金・仕様は変更される可能性があります。最新情報は各サービスの公式サイトをご確認ください。

関連記事