【登壇レポート】クラメソおおさか IT 勉強会 Midosuji Tech #8 〜レベル300以上限定LT〜で「Bedrock PolicyでAmazon Bedrock Guardrails利用を強制してみた」というタイトルで登壇しました!

【登壇レポート】クラメソおおさか IT 勉強会 Midosuji Tech #8 〜レベル300以上限定LT〜で「Bedrock PolicyでAmazon Bedrock Guardrails利用を強制してみた」というタイトルで登壇しました!

2026.02.08

はじめに

こんにちは、チーズナンが大好きなコンサルティング部の神野です。

2026年2月4日(水)にクラスメソッド大阪オフィスで開催されたMidosuji Tech #8で「Bedrock PolicyでAmazon Bedrock Guardrails利用を強制してみた」というタイトルで登壇しました!
(実際の登壇タイトルは「Bedrock Guardrailsをアカウント間で共有する方法をまとめてみた(AWS Organizations前提)」だったのですが直感的なタイトルに修正しました)

https://classmethod.connpass.com/event/371782/

マルチアカウント環境でBedrockを使っていると、組織として共通のGuardrailsを各アカウントに強制できないのか?という疑問を持つ方もいるのではないでしょうか。今回はプレビューリリースではあるものの、Bedrock Policyを使って実現する方法を紹介しました。

登壇資料

Amazon Bedrock Guardrailsのおさらい

本題に入る前に、Amazon Bedrock Guardrailsについて軽くおさらいしておきます。

Amazon Bedrock Guardrailsは、生成AIアプリケーションに安全対策を実装するためのAWSマネージドサービスです。有害コンテンツのフィルタリング、特定トピックのブロックなど多様な機能が備わっています。

例えば開発系の話題のみ返信したいチャットボットを作る場合、日常会話をブロックする拒否トピックを設定しておけば、「明日の天気は?」のような日常会話をブロックします。

CleanShot 2026-02-07 at 20.09.22@2x

Strands Agentsでも簡単に使える

私が大好きなStrands Agentsでも、BedrockModelguardrail_idguardrail_versionを指定するだけで使えます。

agent.py
bedrock_model = BedrockModel(
    model_id="global.anthropic.claude-sonnet-4-5-20250929-v1:0",
    guardrail_id="your-guardrail-id",
    guardrail_version="1",
    guardrail_trace="enabled",
)

agent = Agent(
    system_prompt="You are a helpful assistant.",
    model=bedrock_model,
)

guardrailのidやversionを指定すればOKです。詳しくは下記ブログで検証しております。

https://dev.classmethod.jp/articles/strands-agents-amazon-bedrock-guardrails-request-block/

組織として複数アカウントでGuardrailsを共有したい

組織として複数アカウントで同じGuardrailsを共有して、さらに強制できるのかと疑問に思うことがちょくちょくでてきました。

例えば組織として共通の生成AI基盤を作りたい場合、各アカウントで個別にGuardrailsを作成・管理するのは運用したくはなく、管理アカウントで一元管理して、利用アカウントに自動で適用したいといったシーンが思いつきました。

CleanShot 2026-02-07 at 20.11.13@2x

結論として、Bedrock Policy(Preview)を使えば実現できます!

先に結論

ポイントをまとめます。

  • Bedrock Policyを使用すれば、組織全体に同一のGuardrailsを強制できる
  • AWS Organizationsの組織全体だけでなく、特定のOUやアカウント単位での指定も可能
  • アカウントレベルでの強制も可能で、組織レベルとの併用もできる(最も制限が厳しいコントロールが優先)
  • あくまで同一Organizations内に限り、別Organizationsやシングルアカウント同士での共有は不可

https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-enforcements.html

次のセクションから実際にBedrock Policyを適用する手順についてブレイクダウンしていきます。

Bedrock Policyを実際に適用してみる

構成

管理アカウントでGuardrailsを作成し、利用アカウントでそのGuardrailsが強制される構成にします。

CleanShot 2026-02-07 at 20.11.40@2x

手順は大きく3ステップです。

  1. 管理アカウントでGuardrailsを作成し、リソースベースポリシーを設定する
  2. AWS OrganizationsでBedrock Policyを有効化・作成・アタッチする
  3. 利用アカウントで動作確認する

管理アカウントでGuardrailsを作成

まずは管理アカウントでGuardrailsを作成します。
今回はわかりやすく「チーズナン」の会話を拒否するトピックを設定しました。(チーズナンは大好きで恨みはないです・・・わかりやすさ重視です・・・ごめんよ・・・)

CleanShot 2026-02-07 at 20.12.02@2x

次に、組織内のアカウントからこのGuardrailsを利用できるようにリソースベースポリシーを作成します。Condition句にaws:PrincipalOrgIDを指定して、Organization全体に公開します。

policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowOrganizationAccess",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "bedrock:ApplyGuardrail",
                "bedrock:GetGuardrail"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-xxxxxxxxxx"
                }
            }
        }
    ]
}

ConditionでOrganization IDを指定して組織内に絞っています。これで自組織のアカウントはこのGuardrailsにアクセス可能となります。

また、特定のOUのみに絞りたい場合はaws:PrincipalOrgPathsを使ったポリシーの書き方も可能です。

policy.json
{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": "*",
        "Action": [
            "bedrock:ApplyGuardrail",
            "bedrock:GetGuardrail"
        ],
        "Resource": "arn:aws:bedrock:us-east-1:xxxxxxxxxxxx:guardrail/guardrail-id",
        "Condition": {
            "ForAnyValue:StringLike": {
                "aws:PrincipalOrgPaths": [
                    "org-id/*/org-unit-id/*"
                ]
            }
        }
    }]
}

こちらはConditionでOUのパスを指定しています。

https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-resource-based-policies.html

AWS OrganizationsでBedrock Policyを有効化・作成・アタッチ

AWS Organizationsの管理コンソールからBedrock Policyを有効化します。

CleanShot 2026-02-07 at 20.13.49@2x

有効化したら、具体的なポリシーを作成します。ポリシーにはリージョン毎に対象のGuardrails ARNを指定します。

bedrock_policy.json
{
  "bedrock": {
    "guardrail_inference": {
      "us-east-1": {
        "config_1": {
          "identifier": {
            "@@assign": "arn:aws:bedrock:us-east-1:12345678901:guardrail/xxx:1"
          },
          "input_tags": {
            "@@assign": "ignore"
          }
        }
      }
    }
  }
}

最後に、作成したポリシーをアタッチします。Root、指定のOU、アカウント単位で紐付け可能です。今回はRootにアタッチしました。(地味にこのポリシーをアタッチし忘れて反映されていない・・・?ってことがあったので忘れないように注意しましょう)

CleanShot 2026-02-07 at 20.14.19@2x
これで準備完了です!

利用アカウントで動作確認

利用アカウントの状況を確認

利用アカウントのBedrockコンソールを見ると、アカウント自体にはGuardrailsは存在しませんが、Organization-level enforced guard railsに先ほど管理アカウントで作成したGuardrailsが表示されています。

CleanShot 2026-02-07 at 21.45.22@2x

良さげな匂いがしますね。

Converse APIで実行してみる

この状態でConverse APIを実行してみます。チーズナンの話題で質問しますが、ガードレールの指定は特にしていません。

実行コマンド
aws bedrock-runtime converse \
    --model-id us.anthropic.claude-haiku-4-5-20251001-v1:0 \
    --messages '[{"role":"user","content":[{"text":"チーズナンって美味しいよね"}]}]' \
    --region us-east-1

Guardrailsによる固定文言が返却されました!

CleanShot 2026-02-08 at 09.50.05@2x

実行結果
{
    "output": {
        "message": {
            "role": "assistant",
            "content": [
                {
                    "text": "申し訳ありませんが、モデルはこの質問に回答できません。"
                }
            ]
        }
    },
    "stopReason": "guardrail_intervened",
    "usage": {
        "inputTokens": 0,
        "outputTokens": 0,
        "totalTokens": 0
    },
    "metrics": {
        "latencyMs": 608
    }
}

stopReasonguardrail_intervenedになっていますね。アカウント自体にGuardrailsがなくても、組織レベルで強制されています!

Strands Agentsでも拒否される

Strands Agentsでも同様にGuardrailsは特に指定せずに実行してみます。

main.py
from strands import Agent
from strands.models.bedrock import BedrockModel

# Bedrockモデルの設定(Claude Sonnet)
model = BedrockModel(
    model_id="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
    region_name="us-east-1",
)

# エージェントの作成
agent = Agent(model=model)
# チーズナンについて質問
response = agent("チーズナンについて教えて")
print(response)

こちらもGuardrailsは特に指定していないにもかかわらず、実行すると「申し訳ありませんが、モデルはこの質問に回答できません。」と拒否されました!(print文を仕込んでいてたので、2回メッセージが表示されています)

CleanShot 2026-02-07 at 21.46.19@2x

AIエージェントに対して組織レベルでGuardrailsを強制したい場合、利用者側は何もしなくても勝手に適用される点が嬉しいですね。

アカウントレベルでの強制もできる

今回は組織レベルでGuardrailsを強制しましたが、アカウントレベルでも同じことが可能です。リソースベースポリシーの設定と、コンソールから強制オプションを選択すれば設定できます。こちらもプレビュー機能です。

アカウントレベルの場合、リソースベースポリシーは自アカウントのみアクセスを許可する形になります。

policy.json
{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::111222333333:root"
        },
        "Action": [
            "bedrock:ApplyGuardrail",
            "bedrock:SetGuardrail"
        ],
        "Resource": "arn:aws:bedrock:us-east-1:111222333333:guardrail/guardrail-id"
    }]
}

コンソールからCreate account level enforcement guardrailの設定を行えばOKです。

CleanShot 2026-02-07 at 21.46.36@2x

さらに、組織レベル・アカウントレベル・通常のGuardrailsは併用が可能で、併用した場合は最も制限が厳しいコントロールが優先されます。組織全体で共通の安全基準を設けつつ、アカウント毎に追加のルールを重ねるといった運用も考えられますね。

CleanShot 2026-02-07 at 21.46.52@2x

Organizations未使用の場合はIaCが選択肢

AWS Organizationsを使用していない環境でアカウント毎に同じGuardrailsを適用したい場合は、CDKやTerraformなどのIaCツールで同一の設定をデプロイするのが現実的な選択肢になるかと思います。

CleanShot 2026-02-07 at 21.49.58@2x

CDKのBedrock alphaパッケージでL2 Constructを使ってシンプルに実装できます。

cdk.ts
const guardrail = new bedrock.Guardrail(this, 'CheeseNaanGuardrail', {
    guardrailName: 'cheese-naan-blocker',
    description: 'チーズナンに関する話題を拒否するガードレール',
    blockedInputMessaging: 'チーズナンの話はお答えできません。',
    blockedOutputsMessaging: 'チーズナンに関する情報は提供できません。',
});

// カスタムトピックを追加(チーズナンの話題を禁止)
guardrail.addDeniedTopicFilter(
    bedrock.Topic.custom({
        name: 'Cheese_Naan_Topic',
        definition: 'チーズナンに関する話題、チーズナンの作り方、レシピ、おすすめ店、チーズナンの歴史などを含む。',
        examples: [
            'チーズナンの作り方を教えて'
        ],
        inputAction: bedrock.GuardrailAction.BLOCK,
        inputEnabled: true,
        outputAction: bedrock.GuardrailAction.BLOCK,
        outputEnabled: true,
    }),
);

// バージョン作成(本番利用時に推奨)
guardrail.createVersion('v1');

addDeniedTopicFilterで拒否トピックを追加し、createVersionでバージョンを作成しています。

Bedrock PolicyなしでOrganizations内のGuardrailsを使う場合

リソースベースポリシーを設定すればBedrock Policyなしでも別アカウントのGuardrailsを使えるのでは?と思うかもしれませんが、いくつか制約があります。

Converse APIではエラーが起きる

Converse APIで同一Org内の別アカウントのGuardrailsを指定すると、存在しないとエラーが出ます。

実行コマンド
aws bedrock-runtime converse \
    --model-id "us.anthropic.claude-haiku-4-5-20251001-v1:0" \
    --messages '[{"role":"user","content":[{"text":"こんにちは"}]}]' \
    --guardrail-config '{
        "guardrailIdentifier": "arn:aws:bedrock:us-east-1:xxxxxxxxxxxx:guardrail/xxxxxxxxxx",
        "guardrailVersion": "1",
        "trace": "enabled"
    }' \
    --region us-east-1
実行結果
An error occurred (ValidationException) when calling the Converse operation:
The model returned the following errors:
The guardrail identifier or version provided in the request does not exist.

Strands Agentsで使用する場合も同様です。

ApplyGuardrail APIなら使える

一方、推論をせずにGuardrailsの評価のみを行うApplyGuardrail APIなら、同一Orgの別アカウントのGuardrailsも使用できます。

CleanShot 2026-02-07 at 21.51.02@2x

Strands AgentsでApplyGuardrail APIとHooksの合わせ技でAIエージェントでもブロックすることも可能です。若干トリッキーなやり方だと思いますが・・・

使ってみて思ったのですが、Bedrock Policyを使わずにあえてこのやり方をするメリットは薄いように感じます。素直にBedrock Policyを使うのがおすすめです。

質問1:CloudFormation StackSetsで同じGuardrailsを展開するのはどう?

登壇時に「CloudFormation StackSetsで各アカウントに同じGuardrailsをデプロイすればいいのでは?」という質問をいただきました。

CloudFormationのAWS::Bedrock::Guardrailリソースタイプが存在するので、StackSetsを使って複数アカウントに同一設定のGuardrailsをデプロイすること自体は可能です。コンテンツフィルター、拒否トピック、ワードフィルター、機密情報フィルター、コンテキストグラウンディングチェックなど、Guardrailsの機能はサポートされています。

https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-bedrock-guardrail.html

ただ、StackSetsは「同じ設定のGuardrailsを各アカウントに配る」仕組みであり、「Guardrailsの利用を強制する」仕組みではありません。StackSetsで配ったとしても、利用者がGuardrailsを指定せずにConverse APIを呼び出せばスルーできてしまいます。

利用者が意識しなくても勝手にGuardrailsが適用されるケースを優先したければBedrock Policyを選択した方が良いといった形ですかね。

一方で、Bedrock Policyはまだプレビュー機能である点と、AWS Organizationsが前提になる点は考慮が必要です。

StackSetsやCDK・Terraformでの展開に加えて、IAMポリシーのbedrock:GuardrailIdentifier条件キーを使ってGuardrailsの指定を強制する方法もあります。
権限的に呼び出せないことで強制させるといった選択も取れますね。

https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-permissions-id.html

質問2:Guardrails以外のBedrockサービスはマルチアカウントに対応しているのか

もう1つ、「Guardrails以外のBedrockサービス、例えばPrompt Managementはマルチアカウントで呼び出せるのか」とご質問いただきました。

こちらは残念ながら非対応となります。

Guardrailsがいち早くクロスアカウント対応を進めているのは、安全対策という性質上、組織全体で強制するニーズが強いからですかね。今後、他のサービスにもクロスアカウント対応が広がることに期待したいです。

おわりに

Bedrock Policyは現時点ではプレビュー機能ですが、マルチアカウント環境で生成AIのガバナンスを効かせたい場合には有力な選択肢になるかと思います。
Organizations側で一度設定するだけで、利用者側は何も意識しなくてもGuardrailsが自動的に適用されるのは嬉しいですね。

本記事が少しでも参考になりましたら幸いです。最後までご覧いただきありがとうございました!

この記事をシェアする

FacebookHatena blogX

関連記事