セキュリティを設計する ── IAM 強制パターンと VPC Endpoint と KMS
対象読者:機能は動くが、セキュリティレビュー / 監査 / コンプライアンスの観点から「これで本番出していいか」を判断する立場の読者 難易度:★★★★☆(実装ハンズオン) 対象バージョン:
@aws-sdk/client-bedrockv3 系 / AWS CDK v2 想定読了時間:約 50 分 関連章:第 11 章(Guardrails IAM 強制)/ 第 13 章(Log Data Protection)/ 第 17 章 #9(VPC Endpoint 未使用)
なぜセキュリティが Production Ready の本気度を決めるのか
エンタープライズで「AI 機能を入れたい」と言うと、最初に返ってくる質問は機能でも UX でもない。「会社のデータが学習に使われませんよね?」「ログにユーザーの個人情報が残らないですよね?」「監査で説明できますよね?」── この 3 問だ。
LLM API を呼ぶ行為そのものが、エンタープライズではコンプライアンスリスクと見なされる。「外部 API に社内データを投げる」というだけで、情シスから赤旗が上がる。OpenAI 直叩きで PoC を作ったまでは良かったが、「セキュリティレビューで止まった」という相談が多いのは、ここに理由がある。
Bedrock の差別化はここに出る。Bedrock はマネージドサービスでありながら、IAM・VPC・KMS・SCP・Compliance プログラムという AWS のセキュリティ機構をそのまま継承する。そして 2025〜2026 年にかけて、bedrock:GuardrailIdentifier 条件キーや Cross-Account Safeguards といった「Production 強制パターン」が次々に追加された。
本章では、ここまで育てた helpdesk-ai に、4 つの層でセキュリティを着せていく。
graph TB
subgraph "層 4:SCP(組織レベル)"
SCP["承認モデルファミリーのみ許可<br/>Guardrail なし呼び出しを全アカウントで禁止"]
end
subgraph "層 3:IAM(最小権限)"
IAM1["特定モデルのみ呼べる"]
IAM2["Guardrail 必須(条件キー)"]
IAM3["Agent 経由のみ、直接 InvokeModel は Deny"]
IAM4["aws:SourceAccount / aws:SourceArn で<br/>confused deputy 対策"]
end
subgraph "層 2:VPC Endpoint(ネットワーク)"
VPCE["Interface VPC Endpoint<br/>Endpoint policy で VPC 単位の制御<br/>Internet Gateway / NAT 不要"]
end
subgraph "層 1:KMS(暗号化)"
KMS1["保管時:AWS KMS(CMK 指定可)"]
KMS2["転送時:TLS 1.2 以上"]
KMS3["Guardrails / KB / Logs に CMK"]
end
SCP --> IAM1
SCP --> IAM2
SCP --> IAM3
SCP --> IAM4
IAM1 --> VPCE
IAM2 --> VPCE
IAM3 --> VPCE
IAM4 --> VPCE
VPCE --> KMS1
VPCE --> KMS2
VPCE --> KMS3
「全部やる必要があるのか?」と思うかもしれない。答えは イエスだ。1 つでも欠けると、攻撃者・うっかり開発者・退職者・コンプライアンス監査のいずれかから穴が空く。Production Ready は「動く」ではなく「全層で破られない」状態を意味する。
出発点:Bedrock のデータ取り扱いポリシー
技術的な設計に入る前に、最大の前提を確認しておく。これは ch03 で他社比較として触れた話の続きであり、後の ch16 で金融・医療事例の根拠として再登場する伏線でもある。
AWS 公式の Bedrock Security & Privacy は、3 つのことを明言している。
- Your data is not shared with model providers.(顧客データはモデルプロバイダーに共有されない)
- Your data is not used to train the underlying models.(FM の学習に使用されない)
- Bedrock service team も、Anthropic 等のモデルプロバイダーも、推論データにアクセスできない。
図にするとこうなる。
graph LR
A["helpdesk-ai<br/>(顧客アプリ)"] -->|TLS 1.2+| B[Amazon Bedrock]
B -->|"推論のみ"| C[Anthropic / Meta /<br/>Cohere / Mistral など<br/>モデルプロバイダー]
C -.->|"❌ データ非共有<br/>❌ 学習に非使用"| D[(プロバイダー側<br/>データレイク)]
B -->|"暗号化保管"| E[("CMK 暗号化<br/>S3 / DynamoDB")]
style D fill:#fff0f0,stroke:#d33,stroke-dasharray: 5 5
style C fill:#f0f4ff
ここが OpenAI 直叩きから Bedrock への移行の最大動機になる。OpenAI 直叩きだと「OpenAI ↔ 顧客」「AWS ↔ 顧客」の 二重 processor 関係 になり、GDPR・SOC 2・社内データガバナンス上の説明責任が複雑化する。Bedrock なら AWS DPA(Data Processing Addendum)が 1 本で全モデルをカバーするため、プロセッサ関係を一本化できる。
「データが共有されない・学習に使われない」というのは、契約レベルだけでなくアーキテクチャ的にも、Anthropic 等のモデルプロバイダーが顧客の推論データにアクセスできない構造になっている。これが Bedrock のセキュリティ設計のスタート地点である。
層 1:IAM ── 最小権限と「Guardrail 強制」パターン
セキュリティ設計の出発点は IAM だ。Bedrock の IAM 設計には、Production Ready のための定型パターンが 4 つある。すべて helpdesk-ai に適用していこう。
パターン 1:特定モデルのみ呼べる
「Bedrock の全モデルが叩ける」という権限を与えるのは、コスト面でも安全面でも危険だ。helpdesk-ai は Claude Sonnet 4 系(Cross-Region Inference Profile)のみ使う前提なので、それだけ許可する。
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowOnlyApprovedModels",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream"
],
"Resource": [
"arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-4-*",
"arn:aws:bedrock:*:123456789012:inference-profile/us.anthropic.claude-sonnet-4-5"
]
}]
}
ポイントは 2 つ。Cross-Region Inference Profile を使う場合は、foundation-model だけでなく inference-profile の ARN も Allow が必要な点(ch15 で扱う Application Inference Profile も同じ)。そしてバージョン番号は claude-sonnet-4-* のようにワイルドカードで縛ると、マイナーアップデートに追随しやすい。
パターン 2:Guardrail を必ず通すことを強制する(2025-03 追加)
ここが本章の核心の 1 つ目。bedrock:GuardrailIdentifier という IAM 条件キーが 2025 年 3 月に追加され、「Guardrail を通さない呼び出しを IAM レベルで拒否する」ことが可能になった。
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyInvocationWithoutGuardrail",
"Effect": "Deny",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream"
],
"Resource": "*",
"Condition": {
"Null": { "bedrock:GuardrailIdentifier": "true" }
}
}]
}
Null: true は「bedrock:GuardrailIdentifier が設定されていない場合」という意味なので、Guardrail を指定しない呼び出しは IAM が拒否する。「Guardrails を後付けにして、いつか付け忘れる」というアンチパターン(ch17 で再登場)を、IAM の段階で潰せる。
さらに「**特定の Guardrail(自社承認版)**しか使えない」と縛りたい場合は、StringEquals を併用する。
{
"Sid": "AllowOnlyApprovedGuardrail",
"Effect": "Deny",
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"bedrock:GuardrailIdentifier": "arn:aws:bedrock:us-east-1:123456789012:guardrail/helpdesk-prod-v3"
}
}
}
これで「helpdesk-ai は helpdesk-prod-v3 以外の Guardrail を使えない」を IAM で保証できる。「組織で承認した Guardrail Policy」と「アプリで使う Guardrail」のずれを構造的に防ぐ強力な仕組みだ。
パターン 3:Agent 経由のみ許可・直接 InvokeModel を禁止する
ch09 と ch10 で見たように、helpdesk-ai は Bedrock Agents(後に AgentCore)を経由してモデルを呼ぶ。アプリのランタイムロールには Agent 呼び出しの権限だけを与え、InvokeModel への直接アクセスは Deny で塞ぐ。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAgentInvocationOnly",
"Effect": "Allow",
"Action": ["bedrock:InvokeAgent"],
"Resource": "arn:aws:bedrock:us-east-1:123456789012:agent-alias/HELPDESK01/PROD"
},
{
"Sid": "DenyDirectModelInvocation",
"Effect": "Deny",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:*::foundation-model/*"
}
]
}
これで Action Group を迂回して LLM を直接叩く経路が物理的に塞がる。Guardrails も Action Group のフィルタも全部すり抜けて生 prompt を投げる、というショートカットが取れなくなる。
パターン 4:confused deputy 対策(aws:SourceAccount と aws:SourceArn)
Bedrock Agents や Knowledge Bases は、AWS がサービスロールを assume してリソースを操作する。このロールの Trust Policy を雑に書くと「Bedrock サービス自体は誰の依頼でも assume できてしまう」という穴ができる。これが confused deputy 問題で、Agent / KB の Service Role を作るときは必ず aws:SourceAccount と aws:SourceArn で絞る。
{
"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/HELPDESK01"
}
}
}]
}
❌ 悪い例:scope-down なし & PassRole を広く渡す
{
"Effect": "Allow",
"Principal": { "Service": "bedrock.amazonaws.com" },
"Action": "sts:AssumeRole"
}
このうえで Agent 管理者ロールに iam:PassRole を Resource: "*" で渡すと、攻撃者が他の高権限ロールを Bedrock に渡して特権昇格(privilege escalation)できる温床になる。AWS Security Blog はこれを 「現場で最も踏みやすい落とし穴」 と名指ししている。
✅ 良い例:scope-down + PassRole も特定ロールに限定
{
"Sid": "AllowPassRoleForAgentOnly",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/HelpdeskAgentServiceRole",
"Condition": {
"StringEquals": { "iam:PassedToService": "bedrock.amazonaws.com" }
}
}
iam:PassedToService 条件キーで「Bedrock に渡す目的でしか PassRole できない」を強制し、Resource で「helpdesk 専用のサービスロールしか渡せない」を組み合わせる。IAM Access Analyzer の policy check(100+ ルール)で事前検証する習慣も組み込んでおくと、レビュー漏れを機械的に拾える。
層 2:VPC Endpoint(PrivateLink)── インターネットを通さない
「外部 API を呼ぶ」という事実そのものをセキュリティ監査で説明するのは、しんどい。bedrock-runtime への通信が NAT Gateway → Internet Gateway → AWS の public endpoint と外を回るたびに、TLS で守られているとはいえ「インターネット越え」という言葉が監査で引っかかる。
Interface VPC Endpoint(AWS PrivateLink) を使えば、Bedrock への通信を VPC 内で完結させられる。Internet Gateway も NAT Gateway も不要だ。helpdesk-ai のように VPC 内 ECS / Lambda から Bedrock を叩く構成では、これは ほぼ必須 と考えていい(ch17 で「PrivateLink 未使用」をアンチパターンとして再登場させる)。
CDK での実装
import { Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import {
Vpc,
InterfaceVpcEndpoint,
InterfaceVpcEndpointAwsService,
SubnetType,
SecurityGroup,
Peer,
Port,
} from "aws-cdk-lib/aws-ec2";
import { PolicyDocument, PolicyStatement, Effect, AnyPrincipal } from "aws-cdk-lib/aws-iam";
export class HelpdeskNetworkStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const vpc = new Vpc(this, "HelpdeskVpc", { maxAzs: 2 });
// VPC Endpoint 用 SG:VPC CIDR からの HTTPS のみ許可
const endpointSg = new SecurityGroup(this, "BedrockEndpointSg", {
vpc,
description: "Allow HTTPS from VPC CIDR only",
allowAllOutbound: false,
});
endpointSg.addIngressRule(Peer.ipv4(vpc.vpcCidrBlock), Port.tcp(443));
// Endpoint policy:自社承認モデル & 自社 Guardrail のみ許可
const endpointPolicy = new PolicyDocument({
statements: [
new PolicyStatement({
effect: Effect.ALLOW,
principals: [new AnyPrincipal()],
actions: [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream",
],
resources: [
"arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-4-*",
`arn:aws:bedrock:*:${this.account}:inference-profile/us.anthropic.claude-sonnet-4-5`,
],
conditions: {
StringEquals: {
"bedrock:GuardrailIdentifier":
`arn:aws:bedrock:us-east-1:${this.account}:guardrail/helpdesk-prod-v3`,
},
},
}),
],
});
new InterfaceVpcEndpoint(this, "BedrockRuntimeEndpoint", {
vpc,
service: InterfaceVpcEndpointAwsService.BEDROCK_RUNTIME,
subnets: { subnetType: SubnetType.PRIVATE_ISOLATED },
privateDnsEnabled: true,
securityGroups: [endpointSg],
policyDocument: endpointPolicy,
});
// Agent / Knowledge Bases も別 Endpoint で公開
new InterfaceVpcEndpoint(this, "BedrockAgentRuntimeEndpoint", {
vpc,
service: InterfaceVpcEndpointAwsService.BEDROCK_AGENT_RUNTIME,
subnets: { subnetType: SubnetType.PRIVATE_ISOLATED },
privateDnsEnabled: true,
securityGroups: [endpointSg],
});
}
}
Endpoint policy で **「この VPC から出る Bedrock 呼び出しは、承認モデル × 承認 Guardrail の組み合わせに限る」**を縛れるのが効く。IAM ロールが「うっかり広い権限を持っている」場合でも、ネットワーク境界で締めれば事故の被害を抑えられる。**多層防御(defense in depth)**は、こうやって 1 層ずつ重ねる。
PRIVATE_ISOLATED サブネットに置くことで、Internet Gateway / NAT を一切経由せずに Bedrock に到達する。VPC Flow Logs を有効にしておけば「インターネット越えのトラフィックが本当に存在しないこと」を監査で示せる証跡にもなる。
層 3:KMS ── 保管時暗号化と CMK 指定
Bedrock 周辺のデータ保管は、デフォルトで AWS-managed KMS key により暗号化されている。ただし「鍵を自社で持つ」というコンプライアンス要件がある場合は、ほぼすべての地点で Customer Managed Key(CMK) を指定できる。
| 暗号化対象 | CMK 指定可否 | 設定方法 |
|---|---|---|
| Guardrails の Policy / Trace | 可 | CreateGuardrail の kmsKeyId |
| Knowledge Bases のベクトル / 取り込みデータ | 可 | KB 作成時の serverSideEncryptionConfiguration |
| カスタムモデル / ファインチューニングデータ | 可 | CreateModelCustomizationJob の outputDataConfig.kmsKeyId |
| Model Invocation Logs(S3) | 可 | バケット SSE-KMS + Bedrock service principal への許可 |
| Model Invocation Logs(CloudWatch Logs) | 可 | Log Group に CMK を関連付け |
| Agent / AgentCore のセッション・Memory | 可 | AgentCore Memory 作成時に指定 |
転送時は TLS 1.2 以上が強制される。bedrock-runtime の API はすべて HTTPS のみで、TLS 1.0/1.1 はそもそも受け付けない。
Model Invocation Logs の S3 + KMS 暗号化(CDK)
ch13 で見た Model Invocation Logs は、helpdesk-ai のセキュリティ設計では特に CMK 必須で扱うべきデータだ。Guardrails Mask モードを使っていても、Model Invocation Logs の input フィールドには原文 PII がそのまま残る(ch11 で示した落とし穴。ch17 で再登場)。だからログ側を自社鍵で守る意味は大きい。
import { Bucket, BucketEncryption, BlockPublicAccess, ObjectOwnership } from "aws-cdk-lib/aws-s3";
import { Key } from "aws-cdk-lib/aws-kms";
import { PolicyStatement, ServicePrincipal } from "aws-cdk-lib/aws-iam";
const logKey = new Key(this, "BedrockLogsKey", {
description: "CMK for helpdesk-ai Bedrock invocation logs",
enableKeyRotation: true,
});
const logBucket = new Bucket(this, "BedrockLogsBucket", {
encryption: BucketEncryption.KMS,
encryptionKey: logKey,
enforceSSL: true,
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
objectOwnership: ObjectOwnership.BUCKET_OWNER_ENFORCED,
});
// Bedrock サービスから書けるよう、CMK 側で許可を出す
logKey.addToResourcePolicy(
new PolicyStatement({
sid: "AllowBedrockToUseKey",
principals: [new ServicePrincipal("bedrock.amazonaws.com")],
actions: ["kms:GenerateDataKey", "kms:Decrypt"],
resources: ["*"],
conditions: {
StringEquals: {
"aws:SourceAccount": this.account,
},
ArnLike: {
"aws:SourceArn": `arn:aws:bedrock:*:${this.account}:*`,
},
},
})
);
// バケットポリシーで Bedrock からの PutObject を許可
logBucket.addToResourcePolicy(
new PolicyStatement({
sid: "AllowBedrockLogDelivery",
principals: [new ServicePrincipal("bedrock.amazonaws.com")],
actions: ["s3:PutObject"],
resources: [`${logBucket.bucketArn}/AWSLogs/${this.account}/BedrockModelInvocationLogs/*`],
conditions: {
StringEquals: {
"s3:x-amz-acl": "bucket-owner-full-control",
"aws:SourceAccount": this.account,
},
},
})
);
ここでも aws:SourceAccount と aws:SourceArn を入れている。KMS Key Policy にも confused deputy 対策を仕込むのが鉄則。Key Policy で SourceArn を絞らないと、別アカウントの Bedrock 経由で自社キーを使われる経路が理屈上開く。
層 4:SCP ── 組織全体での Guard Rail
ここまでの 3 層は単一アカウント内の話だが、企業規模になると AWS Organizations で複数アカウントを束ねていることが多い。組織レベルで「全アカウント共通の禁止事項」を強制するのが Service Control Policy(SCP) だ。
helpdesk-ai のような業務 AI を組織全体で展開する場合、最低でも次の 2 つの SCP を OU レベルで強制しておく。
SCP 1:承認モデルファミリーのみ許可
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyUnapprovedFoundationModels",
"Effect": "Deny",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream"
],
"Resource": "*",
"Condition": {
"ArnNotLike": {
"bedrock:FoundationModel": [
"arn:aws:bedrock:*::foundation-model/anthropic.*",
"arn:aws:bedrock:*::foundation-model/amazon.nova-*"
]
}
}
}]
}
「bedrock:FoundationModel 条件キーで承認済みファミリー(Anthropic と Amazon Nova のみ)以外は組織全体で Deny する」というパターン。Inference Profile 経由でも foundation model ARN は条件キーから読めるため、CRIS を使っていてもこの SCP は効く。「あるアカウントの開発者が試しに新しい外部モデルを叩く」が起きなくなる。
SCP 2:全アカウントで Guardrail なし呼び出しを禁止
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "OrgWideDenyInvocationWithoutGuardrail",
"Effect": "Deny",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:Converse",
"bedrock:ConverseStream"
],
"Resource": "*",
"Condition": {
"Null": { "bedrock:GuardrailIdentifier": "true" }
}
}]
}
層 3 で IAM ポリシー単体に書いたものと同じ Deny を 組織レベルに昇格する。各アカウントの IAM ポリシーがどう書かれていようと、Guardrail を通さない呼び出しは組織全体で物理的に不可能になる。
Cross-Account Safeguards(2026-04 GA)
2026 年 4 月に GA した Cross-Account Safeguards は、SCP のさらに上位互換的な機能だ。組織の中央アカウントが定義した Guardrail Policy を、全 OU・全アカウントの Bedrock 呼び出しに自動適用できる。
これまで「子アカウントの開発者が Guardrail を付けて InvokeModel する」のを SCP で強制してきた。Cross-Account Safeguards は **「子アカウントが Guardrail を指定しなくても、中央定義の Guardrail が必ず重なって動く」**という挙動になり、ガバナンスが一段強くなる。
helpdesk-ai が小規模な単一アカウント運用なら SCP だけで十分だが、複数事業部・複数子会社で AI 機能を横展開する段階に入ったら、Cross-Account Safeguards に乗せ替えるのが推奨パターンになる。詳細な設定方法は AWS のリリースブログと最新 docs を必ず参照してほしい(2026-06 時点ではドキュメント整備が進行中)。
コンプライアンス
Bedrock は AWS のコンプライアンスフレームワークをそのまま継承する。helpdesk-ai を金融・医療・公共系で使う想定があるなら、以下の認証状況を抑えておく。
| 標準 | 対応 |
|---|---|
| SOC 1 / 2 / 3 | 対応(AWS SOC レポートに Bedrock 含まれる) |
| ISO 9001 / 27001 / 27017 / 27018 / 27701 / 22301 / 20000 | 対応 |
| CSA STAR Level 2 | 対応 |
| HIPAA | HIPAA Eligible Service(PHI 取り扱い可、BAA 締結が前提) |
| GDPR | AWS DPA でカバー。前述のとおり processor 関係を一本化できる |
| FedRAMP High | AWS GovCloud (US-West) で対応 |
| PCI DSS / IRAP | 最新は AWS Compliance Programs を参照 |
ポイントは HIPAA Eligible Service であること。医療系で PHI(保護対象保健情報)を扱う AI を組む場合、Bedrock は BAA(Business Associate Addendum)を AWS と締結することで、OpenAI 直叩きでは詰みがちな要件にそのまま乗せられる。これは ch16 で Pfizer の事例を見るときに効いてくる前提条件でもある。
データレジデンシー ── In-Region / Geographic / Global の 3 モード
「データはどこに置かれ、推論はどこで実行されるか」── これも金融・公共で必ず聞かれる質問だ。Bedrock の Cross-Region Inference(CRIS)には 3 モードがあり、要件に応じて選ぶ。
graph TB
A[helpdesk-ai source region: ap-northeast-1] --> M{推論モード}
M -->|In-Region| B["同一リージョンで完結<br/>強い residency 要件向け"]
M -->|Geographic CRIS<br/>例: Japan profile| C["日本国内リージョン群<br/>東京・大阪に分散<br/>residency 維持"]
M -->|Global CRIS| D["全グローバル分散<br/>最安・最速だが<br/>residency 制約なし"]
B --> L[("CloudWatch / CloudTrail /<br/>Model Invocation Logs<br/>はすべて source region に書かれる")]
C --> L
D --> L
| モード | 推論実行先 | 用途 | 注意点 |
|---|---|---|---|
| In-Region | source region のみ | 強い residency 要件、金融・医療・公共 | スループット上限あり、スロットル多発時に逃げ場がない |
| Geographic CRIS | 同一地理圏(例:Japan = 東京 + 大阪)に分散 | residency 維持しつつ可用性確保 | 「データが日本国内に留まる」を維持できる |
| Global CRIS | 全グローバル分散 | 最安・最高スループット | residency 要件があるとアウト |
ここで重要な事実:CloudWatch メトリクス・CloudTrail・Model Invocation Logs は、すべて source region(= リクエストを出したリージョン)に書かれる。Geographic / Global CRIS で推論自体は他リージョンへ飛んでも、ログは source に留まる。「推論は別リージョンに行くがログは日本に残る」という設計が成立するため、「ログだけは絶対に日本国内」という社内ガバナンスとも整合させやすい。
helpdesk-ai のデフォルトは Geographic CRIS(Japan profile) を推奨する。これが「速度・可用性・residency」の妥協点として最も無難だ。In-Region 専用は「金融機関の特定業務」など、明示的に外に出せないユースケース限定。マルチリージョン化の具体的な構築方法は 付録 A で深掘りする。
helpdesk-ai のセキュリティ実装まとめ
ここまで設計した 4 層を、helpdesk-ai のスタックに反映する。CDK の infra/cdk-stack.ts から見ると、こうレイヤー分けされる構成になる。
import { Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import { HelpdeskNetworkStack } from "./network-stack"; // VPC + Endpoint
import { HelpdeskCryptoStack } from "./crypto-stack"; // CMK + Log Bucket
import { HelpdeskIamStack } from "./iam-stack"; // 最小権限 + Guardrail 強制
import { HelpdeskAppStack } from "./app-stack"; // ECS / Lambda / Agent
export class HelpdeskRootStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const crypto = new HelpdeskCryptoStack(this, "Crypto");
const network = new HelpdeskNetworkStack(this, "Network");
const iam = new HelpdeskIamStack(this, "Iam", {
approvedGuardrailArn:
`arn:aws:bedrock:us-east-1:${this.account}:guardrail/helpdesk-prod-v3`,
approvedAgentAliasArn:
`arn:aws:bedrock:us-east-1:${this.account}:agent-alias/HELPDESK01/PROD`,
});
new HelpdeskAppStack(this, "App", {
vpc: network.vpc,
taskRole: iam.taskRole,
logBucket: crypto.logBucket,
});
}
}
- Crypto Stack:CMK と Log Bucket を最初に作る(他の Stack が参照する基盤)
- Network Stack:VPC と Bedrock 用 Endpoint(policy 付き)を作る
- IAM Stack:パターン 1〜4 を組み合わせた
taskRoleを作る(Guardrail 強制 + Agent 経由のみ + confused deputy 対策込み) - App Stack:ECS / Lambda は
taskRoleを assume し、VPC 内で動き、Endpoint 経由で Bedrock を呼ぶ
そして組織レベルで SCP 2 種を OU に attach し、将来的に Cross-Account Safeguards へ移行する余地を残す。これが本章で目指した helpdesk-ai の Production Ready セキュリティ設計の完成形だ。
次章への接続
これで helpdesk-ai は、**機能(ch06–ch10)・安全性(ch11)・観測(ch13)・セキュリティ(ch14)**の 4 つが揃った。Production Ready の壁 1・壁 2 は、大きく崩れた。
最後に残るのが コストだ。セキュリティをここまで重ねた helpdesk-ai を、月いくらで運用できるのか。Provisioned Throughput を買うのか、On-Demand のままでいくのか。Intelligent Prompt Routing と Prompt Caching をどう組み合わせれば、想定の 10 倍コストを避けられるのか。
次章 ch15 で「コストを設計する」を扱い、Part 3「Production Ready に仕上げる」を締めくくる。そして Part 4 では、ここまで設計してきた前提を 実際の金融・医療事例(ch16)で検証する。「PrivateLink 未使用」「Guardrails 後付け」「IAM 権限過大」といった本章のアンチパターンは、ch17 で 9 個のアンチパターンとして集約する。
章末まとめ
- Bedrock の差別化は「データを学習に使わない・モデルプロバイダーに渡さない」というデータ取り扱いポリシーに出る。これが OpenAI 直叩きから移行する最大動機
- IAM 4 パターン:(1) 特定モデルのみ許可、(2)
bedrock:GuardrailIdentifier条件キーで Guardrail 強制、(3) Agent 経由のみ・直接 InvokeModel 禁止、(4)aws:SourceAccount/aws:SourceArnで confused deputy 対策- VPC Endpoint(PrivateLink) で Bedrock 通信を VPC 内に閉じ、Endpoint policy で「承認モデル × 承認 Guardrail」に縛る。Internet Gateway / NAT 不要
- KMS CMK は Guardrails / KB / Model Invocation Logs / Agent Memory に指定可能。特に Mask モードでも残る
input原文の保護に効く- SCP で組織レベルに「承認モデルファミリーのみ」「Guardrail なし呼び出し禁止」を昇格。Cross-Account Safeguards(2026-04 GA) が次の選択肢
- コンプライアンスは SOC・ISO・CSA STAR・HIPAA Eligible・GDPR・FedRAMP High(GovCloud)。PCI DSS / IRAP は最新の AWS Compliance Programs を参照
- データレジデンシーは In-Region / Geographic CRIS / Global CRIS の 3 択。CloudWatch・CloudTrail・Model Invocation Logs はすべて source region に書かれる。マルチリージョン設計の詳細は 付録 A
- 次章は「コストを設計する」── Production Ready の最後のピース