Amazon BedrockのClaudeをIAM制御する

Amazon BedrockのClaudeをIAM制御する

2026.05.08

こんにちは、せーのです。

企業にてClaudeを導入する際にアクセス制限をかけたい、という要望をよく伺います。
社外からの利用を絞りたい、出口を決め打ちしたい、といったニュアンスです。一方で、どのプロダクト経路で Claude を使うかによってそもそもできることがかなり変わります。

そこで今回は、Amazon Bedrock 上の Claude(Anthropic 系モデル)なら、IAM(必要なら SCP)で「誰が・どのモデルを・どの条件で呼べるか」を組織のポリシーとして束ねられるのでは、という筋を立てて、CLI とポリシーを実際に当て込んでみました 。ネットワークの allowlist と完全に同じではありませんが、「鍵やクレデンシャルを持てる主体だけが、許可した経路だけ通る」という意味では、統制の主語を AWS 側に寄せられる のがポイントだと思っています。

本文では Bedrock 上で Claude をどう IAM で縛るか を中心に整理しつつ、あわせて AWS で Claude を扱う経路が増えてきた話(Bedrock・Marketplace・Claude Platform on AWS)にも触れます。

AWS で Claude を扱う3つの筋(おさらい)

いま話題になりやすいのは、ざっくり次の3つです。

経路 ざっくりした位置づけ
Amazon Bedrock 開発者向け。複数ベンダの基盤モデルを API で利用。Guardrails や Knowledge Bases など AWS 側の枠組みと組み合わせやすい。
Claude for Enterprise(AWS Marketplace) ビジネスユーザー向け SaaS。Marketplace 経由の調達・一括請求。コーディング前提ではない。
Claude Platform on AWS Anthropic のプラットフォーム体験を、IAM・請求・CloudTrail を AWS 側で束ねる方向のサービス(公開情報では Coming Soon / Private Beta などのステータス)。

違いを整理すると、データや統制を AWS 内に寄せたい・マルチモデルも見たいなら BedrockClaude のネイティブ機能(公式ページに挙がっている Web Search や MCP など)を AWS 管理下で使いたいなら PlatformSaaS として社内に配りたいなら Marketplace の Enterprise、というイメージです。要件次第で「併用」も普通にありえます。

Bedrock の制御の考え方

Amazon Bedrock では、典型的には bedrock:InvokeModelbedrock:InvokeModelWithResponseStream などの権限を、基盤モデルの ARN で絞り込みます。ARN の形は次のようなイメージです。

arn:aws:bedrock:{region}::foundation-model/{model-id}

公式には、特定モデルを Organization 全体で拒否する SCP の例なども掲載されています(後述の参考資料)。

Condition キーで柔軟に絞る

サービス認可リファレンスには、推論リクエストに紐づく Condition キーがまとまっています。よく使いそうなものだけ抜き出すと、次のような整理です。

Condition キー 用途のイメージ
bedrock:modelId モデル ID(ワイルドカード可)で許可・拒否を切る。ARN 差し替えに強い。
bedrock:InferenceProfileArn 特定の推論プロファイル経由だけ許可する、など。
bedrock:GuardrailIdentifier Guardrail 付きリクエストだけ通す、といったコンプライアンス寄りの制御。
bedrock:ServiceTier サービスティアによる制限・コスト寄りの整理。
bedrock:BearerTokenType Claude Platform on AWS 連携まわりで効いてくるキー(今後の設計で意識する場面がありそうです)。
bedrock:PromptRouterArn プロンプトルーター経由を強制したいとき。

SCP では Resource: "*" にして Condition で絞ると、モデル ID の表現をワイルドカードに寄せやすく、将来のマイナーバージョンにも追従しやすいです。

公式に近いポリシー例(特定 Claude を拒否)

次は、特定の Claude モデルへの推論を拒否する例です。CreateModelInvocationJob も含めておくと、バッチ系も同じ意図で止めやすいです。

{
  "Version": "2012-10-17",
  "Statement": {
    "Sid": "DenyInference",
    "Effect": "Deny",
    "Action": [
      "bedrock:InvokeModel",
      "bedrock:InvokeModelWithResponseStream",
      "bedrock:CreateModelInvocationJob"
    ],
    "Resource": "arn:aws:bedrock:*::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
  }
}

モデル ID にワイルドカードを使えば、anthropic.claude* のように Claude 系をまとめて拒否する、といった書き方もできます。

試したところ、特定の基盤モデル ARN に対する bedrock:InvokeModel の明示 Deny を入れた状態では、InvokeModelConverseAccessDeniedException になりました。Converse のエラーメッセージ側でも、拒否されたアクションは bedrock:InvokeModel と表示されていました。違いを整理すると、Converse を使っていても、モデル推論まわりの認可評価では bedrock:InvokeModel が効く、というイメージです。StartAsyncInvoke など別 API は、運用で使うものごとに同様にステージングで確認してください。

結果:

Converse operation:
not authorized to perform: bedrock:InvokeModel
with an explicit deny in an identity-based policy

bedrock:modelId で旧モデルだけ落とす例

Condition だけで「レガシーっぽいモデル ID」を落とす例です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyLegacyClaudeModels",
      "Effect": "Deny",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "bedrock:modelId": [
            "anthropic.claude-v2*",
            "anthropic.claude-instant-v1*"
          ]
        }
      }
    }
  ]
}

やってみた:CLI とポリシーを触ってみる

以下は 検証用アカウントにて行ったものです。本番 OU に SCP を貼る前に、影響範囲(他の Bedrock 操作が bedrock:* Deny に巻き込まれないか等)を必ずレビューしてください。

Step 1: 利用可能な Claude 系モデルを眺める

aws bedrock list-foundation-models \
  --region ap-northeast-1 \
  --query 'modelSummaries[?contains(modelId, `anthropic.claude`)].[modelId,modelName]' \
  --output table

特定 ID のメタデータだけ見る場合は次です。

aws bedrock get-foundation-model \
  --region ap-northeast-1 \
  --model-identifier anthropic.claude-3-5-sonnet-20240620-v1:0

Step 2: IAM ポリシーとして登録する

例として、Claude 3.5 Sonnet(特定 ID)への推論を拒否するポリシーをファイル deny-claude35-sonnet.json に保存したとします。

aws iam create-policy \
  --policy-name DenyClaude35Sonnet \
  --policy-document file://deny-claude35-sonnet.json

あとは、このポリシーを 検証用ロールにアタッチして、期待どおり拒否になるかを確認します。

結果:

  • InvokeModel: AccessDeniedException
  • Converse: AccessDeniedException
Converse operation:
not authorized to perform: bedrock:InvokeModel
with an explicit deny in an identity-based policy

Step 3: 「Claude 以外の基盤モデルは使わせない」方向の Deny

Resource: "*" に対して **NotResource で「除外する ARN パターン」**を指定する書き方は、IAM ではよくあるパターンです(カスタムモデルや別リソース種別が混ざる環境では副作用が出やすいので、ポリシーシミュレータと実機の両方で確認してください)。

同じ検証では、上に近い NotResource: arn:aws:bedrock:*::foundation-model/anthropic.claude* の Deny を入れた状態で、Claude 3 Haiku(東京)の InvokeModel は成功し、非 Claude 側は Amazon Nova Lite(バージニア北部)の Converse が拒否されるところまで確認できました。リージョンやモデル ID が違うと ARN も変わるので、本番では「許可したい/止めたいモデル」ごとに当て込みが必要です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyNonClaudeFoundationModels",
      "Effect": "Deny",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": "*",
      "NotResource": "arn:aws:bedrock:*::foundation-model/anthropic.claude*"
    }
  ]
}

検証コマンド(例):

aws bedrock-runtime converse \
  --region us-east-1 \
  --model-id amazon.nova-lite-v1:0 \
  --messages '[{"role":"user","content":[{"text":"hi"}]}]' \
  --inference-config '{"maxTokens":8}'

結果:

Nova Converse operation:
not authorized to perform: bedrock:InvokeModel
on resource: arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-lite-v1:0
with an explicit deny in an identity-based policy

Step 4: リージョンを東京に寄せたい(例)

次の例は、InvokeModel を東京以外のリージョン要求で Denyするイメージです。実際の要件に合わせてアクションやリージョン条件は調整してください。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Deny",
    "Action": "bedrock:InvokeModel",
    "Resource": "*",
    "Condition": {
      "StringNotEquals": {
        "aws:RequestedRegion": "ap-northeast-1"
      }
    }
  }
}

Organization 全体に効かせたい場合は、同じ JSON を SCP として作り、対象 OU にアタッチします。CLI のイメージだけ置いておきます(p-xxxxxxxxxxxxou-xxxx-xxxxxxxx はダミーです)。

今回の実機確認は IAM アイデンティティポリシー上の明示 Deny が中心で、OU への SCP アタッチそのものは未実施です(影響範囲が広いため)。Deny が優先されるという評価ロジックは公式ドキュメントに沿って説明しつつ、拒否時の挙動自体は IAM 側の明示 Deny で再現できました。

aws organizations create-policy \
  --name "BedrockTokyoRegionOnlyInvokeModelExample" \
  --type SERVICE_CONTROL_POLICY \
  --description "Example: deny InvokeModel outside ap-northeast-1" \
  --content file://scp-bedrock-region.json

aws organizations attach-policy \
  --policy-id p-xxxxxxxxxxxx \
  --target-id ou-xxxx-xxxxxxxx

Step 5(任意): Guardrail 未指定を拒否したい場合

次の例は、bedrock:GuardrailIdentifier が付いていないリクエストを Deny したいという意図のたたき台です。試した限りでは Null 条件どおり、Guardrail 未指定の InvokeModel / Converse は拒否されました。一方で、有効な Guardrail ID を付けたリクエストが意図どおり通るかは、今回の検証では未確認です。本番で「必須化」するなら、許可パスもセットで当て込んでください。

結果:

  • Guardrail未指定の InvokeModel: AccessDeniedException
  • Guardrail未指定の Converse: AccessDeniedException
  • Converse の場合もエラー文では bedrock:InvokeModel の明示Denyとして表示された
{
  "Version": "2012-10-17",
  "Statement": {
    "Sid": "RequireGuardrailExample",
    "Effect": "Deny",
    "Action": [
      "bedrock:InvokeModel",
      "bedrock:InvokeModelWithResponseStream"
    ],
    "Resource": "*",
    "Condition": {
      "Null": {
        "bedrock:GuardrailIdentifier": "true"
      }
    }
  }
}

CloudTrail での見え方

Bedrock の API 呼び出しは CloudTrail に載ります。InvokeModel あたりを追うときは、次のようなフィールドが手がかりになりやすいです。

  • 誰が: userIdentity
  • いつ: eventTime
  • どのモデルか: 成功イベントでは requestParameters.modelId を確認できました(InvokeModel / Converse とも)。一方、拒否(AccessDenied)イベントでは requestParametersnull になるケースがあり、どのモデルで弾かれたかは errorMessage に含まれるリソース ARN から読み取る必要がありました。イベントごとに生ログを一度見るのが確実です。
  • どこから: sourceIPAddress など

結果:

{
  "eventName": "InvokeModel",
  "requestParameters": {
    "modelId": "anthropic.claude-3-haiku-20240307-v1:0"
  },
  "additionalEventData": {
    "inputTokens": 13,
    "outputTokens": 4
  }
}
{
  "eventName": "Converse",
  "requestParameters": {
    "modelId": "anthropic.claude-3-haiku-20240307-v1:0",
    "inferenceConfig": {
      "maxTokens": 8
    }
  }
}
AccessDenied event:
requestParameters: null
errorMessage: ... on resource: arn:aws:bedrock:...:foundation-model/...

コンソールや CLI でざっくり一覧する例です。

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=InvokeModel \
  --start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) \
  --query 'Events[*].[EventTime,Username,Resources[0].ResourceName]' \
  --output table

ログが S3 に溜まっているなら、CloudWatch Logs Insights などで集計するイメージです。

fields @timestamp, userIdentity.principalId, requestParameters.modelId
| filter eventName = "InvokeModel"
| stats count() by requestParameters.modelId
| sort count() desc

Claude Platform on AWS(Coming Soon 周辺の整理)

Claude Platform on AWS は、公式ページの説明によれば、claude.ai に近い体験を、AWS アカウントの IAM・請求・CloudTrail と組み合わせて使えるようにする方向のサービス、という位置づけです。細かい機能差や提供形態はリリース時点のドキュメントが正なので、「今すぐ Organization で張る SCP」の本文は Bedrock 側として切り分けるのが安全です。

Bedrock との違いは、社内リサーチでは **「推論インフラのオペレーターが AWS か Anthropic か」「Guardrails / Knowledge Bases が使えるのは主に Bedrock か」**といった軸で整理していました。俯瞰記事としては、DevelopersIO 英語版の比較記事も参考になります(参考資料にリンクします)。

Claude for Enterprise(AWS Marketplace)の位置づけ(補足)

Claude for Enterprise を Marketplace から購入するという選択肢もあります。価格や最低シート数などは 公開ページの数値が変わりうるので、記事時点の情報として読み、実際の調達時は必ず最新の Marketplace 表示を確認してください。

ちなみに弊社経由でも購入できます。

https://classmethod.jp/services/claude/

まとめ

  • 「Claude に IP 制限を」という話がある場合、まずは Bedrock 経由に寄せて IAM / SCP で統制する、という筋を考えてみましょう。完全なネットワーク allowlist の代替ではありませんが、認可の主語を AWS に置けるのが大きいです。
  • いま Organization で実効性を出しやすいのは、Amazon Bedrock の IAM / SCP と Condition キーです。bedrock:modelId を押さえると、モデル ID の世代交代にも追従しやすいです。
  • 実機確認できた範囲(検証用アカウント・2026-05-08) では、InvokeModel の明示 Deny が Converse にも効くこと、NotResourceClaude 系は通しつつ非 Claude を止められること、Guardrail 未指定を Null 条件で止められること、が分かりました。
  • CloudTrail では 成功イベントの modelId 集計は requestParameters が手がかりになりやすい一方、拒否イベントは errorMessage 側の ARN も見る必要がありました。SCP の OU アタッチそのものは未実施なので、Organization 適用は別途ステージングで。
  • 監査は CloudTrail(+ Athena / QuickSight など)に繋げるのが定番ルートです。

どうぞ参考にしてみてください。

参考資料


生成AI活用はクラスメソッドにお任せ

過去に支援してきた生成AIの支援実績100+を元にホワイトペーパーを作成しました。御社が抱えている課題のうち、どれが解決できて、どのようなサービスが受けられるのか?4つのフェーズに分けてまとめています。どうぞお気軽にご覧ください。

生成AI資料イメージ

無料でダウンロードする

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事