AWS WAF を用いた Amazon Bedrock AgentCore Runtime のセキュリティ強化
AWS は、生成 AI エージェントを本番環境で安全に運用するための新しいアーキテクチャパターンを提供し、AgentCore Runtime の認証要件と ALB のヘルスチェックの競合問題を解決する。
キーポイント
セキュリティ統合の必要性と課題
Amazon Bedrock AgentCore を本番 API エンドポイントとしてデプロイする際、AWS WAF による保護が必要だが、既存の CloudFront や API Gateway ではキャッシュや二重認証の問題が発生し、インターネットFacing ALB が唯一の選択肢となる。
ヘルスチェックと認証の競合解決
AgentCore Runtime は SigV4 または OAuth 認証を必須とするが、ALB の標準的なヘルスチェックは未認証リクエストを送信するため失敗する。この矛盾を解消するための具体的なアーキテクチャパターンが提示される。
2 つの実装パターンの提案
1 つ目は ALB と VPC エンドポイント間に AWS Lambda を配置してリクエスト変換を行う方法、2 つ目は直接 ENI IP に接続する Lambda なし方式であり、どちらも SigV4 および OAuth (Cognito JWT) に対応している。
セキュリティバックドアの封鎖
直接アクセスを可能にするパターンにおいても、リソースポリシーを設定することで WAF を経由しないトラフィックを防ぎ、セキュリティホールを完全に塞ぐ手法が解説されている。
VPCE を介した Bedrock エージェントへのリダイレクト
AWS WAF の保護下にある Lambda が、環境変数で定義された VPC Endpoint (VPCE) の DNS 名を使用して Amazon Bedrock AgentCore Runtime に安全に通信しています。
リクエストヘッダーの転送と認証維持
Lambda ハンドラーは、クライアントから受信した Authorization ヘッダーをそのまま転送し、Bedrock エージェントへのアクセス制御を維持しています。
Pattern 1 のトレードオフ
Lambda プロキシを使用するパターンでは、コールドスタートにより50〜200msのレイテンシが発生しコストと複雑性が増加しますが、リクエスト変換やカスタムログ制御における柔軟性が得られます。
影響分析・編集コメントを表示
影響分析
この記事は、生成 AI エージェントを大規模かつ安全に本番環境で運用する際の具体的な実装障壁(ALB との認証競合)を解消する重要な指針となる。AWS WAF を活用したセキュリティ強化と、複雑な認証フローを維持しつつ可用性を担保するアーキテクチャは、企業の AI 導入におけるインフラ設計の標準化に寄与する。
編集コメント
生成 AI エージェントのセキュリティ実装において、認証プロトコルとインフラストラクチャの相互運用性は常に課題となりますが、今回の AWS の提案は実務レベルで即座に適用可能な解決策を提供しています。特に Lambda を介さない直接接続オプションは、レイテンシを最小化しつつセキュリティを担保する上で非常に価値が高いです。
生成 AI エージェントを Amazon Bedrock AgentCore としてプロダクション API エンドポイントにデプロイする際、AWS WAF を通じて Web アプリケーションファイアウォールポリシーの適用、レート制限の実施、一般的な Web 脅威からの保護、監査コントロールの強化などを検討したい場合があります。
AWS WAF は、Elastic Load Balancing の Application Load Balancers (ALB)、Amazon CloudFront 配信、および Amazon API Gateway REST API と統合されています。Amazon CloudFront はキャッシングとコンテンツ配信のために設計されており、エージェントの呼び出しはリアルタイムかつ動的であるため、キャッシングは適用されません。また、Amazon API Gateway は独自の認証およびリクエスト変換レイヤーを追加するため、AgentCore に組み込まれた SigV4 および OAuth の処理との間で二重認証の問題が発生する可能性があります。その結果、インターネットに公開された ALB が統合ポイントとして残ります。ALB はヘッダーを透過的に通過させ、VPC 内部のルーティングをサポートし、AWS WAF WebACL に直接接続します。そこから、Bedrock AgentCore データプレーンサービス用の VPC インターフェースエンドポイントを介してトラフィックを AgentCore へルーティングします。
ここに課題が生じます。ALB(Application Load Balancer)には、バックエンドのターゲットが応答可能であることを確認するためのヘルスチェックが必要です。しかし、AgentCore Runtime には、ヘルスチェックリクエストを含むすべての API 呼び出しに対して、認証(SigV4 または OAuth)が要求されます。標準的な ALB のヘルスチェックは認証されていないリクエストを送信するため、そのままでは失敗してしまいます。認証情報なしでヘルスチェックを機能させつつ、生産環境のトラフィックは認証された状態で AgentCore に転送する仕組みが必要です。
本記事では、この課題に対処する 2 つのアーキテクチャパターンを紹介します。両方のパターンとも、インターネットFacing の ALB と AWS WAF を使用し、VPC Interface Endpoint を経由して AgentCore Runtime へトラフィックをルーティングします。パターン 1 では、ALB と VPC エンドポイントの間に AWS Lambda プロキシを配置し、リクエスト変換に対する完全な制御権を得ます。パターン 2 は、ALB から直接 VPC エンドポイントの ENI IP アドレスへアクセスし、Lambda を経由するステップを完全に排除します。また、リソースポリシーを用いてこの直接アクセス用のバックドアを閉鎖し、トラフィックが AWS WAF のみを通過するようにする方法も解説します。両方のパターンは、SigV4 および OAuth(Amazon Cognito JWT)認証を用いたエンドツーエンドのテスト済みです。
アーキテクチャの概要
2 つのパターンは共通の基盤を共有しています。クライアントアプリケーションは、SigV4 シグネチャまたは OAuth Bearer トークンのいずれかを用いて認証されたリクエストをインターネット公開 ALB (Application Load Balancer) に送信します。AWS WAF は、ALB が VPC エンドポイント ENI (Elastic Network Interface) へ HTTPS ポート 443 で転送する前にリクエストを検査します。AgentCore は認証を検証し、リクエストを内部ポート 8080 のランタイムコンテナにルーティングします。2 つのパターンの違いは、ALB と VPC エンドポイントの間に何があるかという点です。

高レベルアーキテクチャ、クライアント → AWS WAF → ALB → VPC エンドポイント (PrivateLink) → AgentCore ランタイムコンテナ
このアーキテクチャには 4 つの構成要素があります。
- AWS WAF は ALB にアタッチされ、AWSManagedRulesCommonRuleSet などの管理ルールグループを通じてレート制限、SQL インジェクション保護、XSS フィルタリング、ボット制御を提供します。
- ALB はインターネット指向で、ポート 443 で HTTPS リスナーを持ち、トラフィックを VPC エンドポイント ENI IP ターゲットにルーティングします。
- VPC インターフェースエンドポイント (com.amazonaws..bedrock-agentcore) は、PrivateLink を介して AgentCore へのプライベート接続を提供します。
- AgentCore Runtime は、エージェントコードを実行する管理コンテナであり、内部ポート 8080 でリスニングし、SigV4 および OAuth 認証の両方をサポートしています。
*注記: Runtime の呼び出しには com.amazonaws..bedrock-agentcore (データプレーン) を使用してください。エンドポイントサービスは 3 つ別々に存在します:bedrock-agentcore(Runtime、Memory、Tools のためのデータプレーン)、bedrock-agentcore-control(コントロールプレーン)、および bedrock-agentcore.gateway(Gateway のみ)。間違ったエンドポイントを使用すると、Runtime にルーティングされません。
前提条件
このウォークスルーを続けるには、以下のものが必要です:
- Amazon Bedrock AgentCore が有効化された AWS アカウント。
- デプロイ済みの AgentCore Runtime(パブリックモードまたは VPC モード)。
- 少なくとも 2 つのアベイラビリティゾーンにまたがる、パブリックサブネットとプライベートサブネットを備えた VPC。
- ALB の HTTPS リスナー用として、同じリージョン内に存在する AWS Certificate Manager (ACM) 証明書。
- OAuth パターン用の Amazon Cognito User Pool、または SigV4 パターン用の AWS クレデンシャル。
- ALB、VPC エンドポイント、および AWS WAF に関する基本的な知識。
以下のセクションでは、AgentCore と AWS WAF を統合するための 2 つのパターンについて説明します。リクエストの変換、カスタムログの取得、または ALB と AgentCore 間の認証変換が必要な場合は、パターン 1 から開始してください。最もシンプルなアーキテクチャで最低限のレイテンシを実現し、追加コンポーネントを不要とする場合は、パターン 2 にスキップしてください。
パターン 1: Lambda プロキシ付き ALB
このパターンでは、ALB の背後に Lambda 関数を配置し、認証ヘッダーを含むリクエストを VPC エンドポイントを経由して AgentCore へ転送します。Lambda 関数により、リクエストが AgentCore に到達する前に、リクエストの変換、認証方式間の変換、またはカスタムログの追加といった計算層を提供できます。
image
パターン 1 のアーキテクチャ、クライアント (JWT) → AWS WAF → ALB → Lambda プロキシ → VPC → VPC エンドポイント → AgentCore Runtime (OAuth オーサライザー)
リクエスト変換や認証方式の変換が必要な場合は、パターン 1 を選択してください。
- リクエスト変換、ヘッダー操作、ペイロードの変更、またはプロトコル変換。
- プロキシ層におけるカスタムログ記録や監査証跡の作成。
- 複数の認証方式間の翻訳。
- ALB とバックエンド間の明示的な計算層(一部のセキュリティポリシーではこれが必須となります)。
VPC エンドポイントの作成
プライベートサブネットに、AgentCore データプレーンサービス用の VPC インターフェースエンドポイントを作成します:
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxxx \
--service-name com.amazonaws.us-east-1.bedrock-agentcore \
--vpc-endpoint-type Interface \
--subnet-ids subnet-aaaa subnet-bbbb \
--security-group-ids sg-xxxxxxxxx*注:VPC インターフェースエンドポイントには、アベイラビリティゾーンごとに時間課金が発生し、さらに GB ごとのデータ処理料がかかります。詳細は VPC の価格設定 をご覧ください。
VPC エンドポイントのセキュリティグループを構成し、ALB のセキュリティグループからのみ HTTPS(ポート 443)への着信を許可してください。これにより、ALB を経由してルーティングされるトラフィックのみが VPC エンドポイントに到達できるようアクセスが制限されます。例:
aws ec2 authorize-security-group-ingress \
--group-id \
--protocol tcp \
--port 443 \
--source-group
## Lambda プロキシの作成
Lambda 関数は ALB からリクエストを受け取り、VPC エンドポイントを経由して AgentCore へ転送します。OAuth の場合、Authorization ヘッダー(ベアータークン)は変更せずに、元のリクエストパスとボディもそのまま保持し、JWT をその状態で AgentCore に届けます。SigV4 の場合、署名は元のリクエストホストに紐付けられているため、VPC エンドポイントへ転送されると無効化されてしまいます。そのため、プロキシ側が実行ロールの資格情報を使用してリクエストを再署名します。
以下の Python スニペットは、核心的な転送ロジックを示しています。この関数は ALB イベントから Authorization ヘッダーを読み取り、VPC エンドポイントの DNS 名を用いてターゲット URL を構築し、元のヘッダーとボディを変更せずにリクエストを転送します。この転送パスは OAuth ベアータークンの場合、そのまま動作します。SigV4 リクエストには追加で再署名ステップが必要であり、これは関連するリポジトリに含まれています。
```python
import json
import urllib3
import os
http = urllib3.PoolManager()
VPCE_DNS = os.environ["VPCE_DNS_NAME"]
def handler(event, context):
path = event.get("path", "/")
headers = event.get("headers", {})
body = event.get("body", "")
method = event.get("httpMethod", "POST")
target_url = f"https://{VPCE_DNS}{path}"resp = http.request(
method,
target_url,
headers={
"Authorization": headers.get("authorization", ""),
"Content-Type": headers.get("content-type", "application/json"),
},
body=body,
)
return {
"statusCode": resp.status,
"headers": {"Content-Type": "application/json"},
"body": resp.data.decode("utf-8"),
}
簡略化のため、上記のスニペットは転送ロジックに焦点を当てています。SigV4署名、クエリ文字列の処理、ALB(Application Load Balancer)のヘルスチェック応答、構造化されたエラーハンドリングを含む、本番環境でそのまま使用可能な完全な実装は、関連する GitHub リポジトリ で利用可能です。
*注意:Lambda プロキシは、リクエスト数と計算時間(GB-秒)に基づいて課金されます。詳細は AWS Lambda の価格設定 をご覧ください。
ALB に Lambda ターゲットグループを設定する
Lambda ターゲットグループを作成し、プロキシ関数を登録して、ALB 上で HTTPS リスナーを作成します。ALB は TLS 終端処理を行い、復号化されたリクエストを Lambda 関数へ転送します。
*注意:Application Load Balancer は時間あたりの課金に加え、トラフィックに基づいて Load Balancer Capacity Unit (LCU) の課金が発生します。詳細は Elastic Load Balancing の価格設定 をご覧ください。
AWS WAF の接続
ALB に AWS WAF WebACL を関連付けます。典型的な初期設定には、一般的なウェブ脅威からの保護のための AWSManagedRulesCommonRuleSet、ソース IP あたりの過剰なリクエストを制限するためのレートベースルール、およびエージェントがブラウザベースのクライアントに公開されている場合の AWSManagedRulesBotControlRuleSet が含まれます。脅威モデルに基づいて管理ルールグループを追加または削除できます。これらは例であり、必須の最小構成ではありません。
*注: AWS WAF は、WebACL あたり月額、ルールあたり、および百万リクエストあたりの検査数に応じて課金されます。詳細は AWS WAF の価格設定 をご覧ください。
*注: Lambda ターゲットグループではパスベースのヘルスチェックは使用されません。ALB は関数を直接呼び出して呼び出し可能であることを確認するため、特別なヘルスチェック設定は不要です。
パターン 1 のトレードオフ
| 側面 | 影響 |
|---|---|
| レイテンシ | リクエストごとに 50〜200 ms 追加されます(Lambda のコールドスタートによるもの)。プロビジョンドコンカレンシーで緩和できます。 |
| コスト | リクエストごとの Lambda 呼び出しコストが発生します。 |
| 複雑さ | デプロイ、監視、維持する追加コンポーネントが必要です。 |
| フレキシビリティ | リクエスト/レスポンスの変換とカスタムログに対して完全な制御権限があります。 |
*注: Lambda プロキシは、リクエストごとに約 50〜200 ms のレイテンシを追加します。レイテンシに敏感なワークロードの場合は、このオーバーヘッドを排除するパターン 2 を検討してください。
パターン 2:ALB から直接 VPC エンドポイントへ
このパターンでは、ALB は HTTPS ポート 443 で VPC Endpoint の ENI IP アドレスに直接ターゲットを設定します。Lambda 関数も Network Load Balancer も存在しません。ALB は認証ヘッダーを AgentCore に透過的に転送します。このアーキテクチャはコンポーネント数が少なく、Lambda プロキシホップが不要になります。

パターン 2 アーキテクチャ、クライアント (JWT または SigV4) → AWS WAF → ALB → VPC Endpoint ENI (HTTPS 443) → AgentCore Runtime
以下の場合にパターン 2 を選択してください:
- コンポーネント数が少なく、よりシンプルなアーキテクチャを望む場合。
- ALB と AgentCore の間でリクエストの変換を行わない場合。
- 追加のホップがなく、最小限のレイテンシを実現したい場合。
- クライアントアプリケーションが SigV4 または OAuth 署名を直接処理する場合。
VPC エンドポイントの作成
プライベートサブネット内で、パターン 1 のステップ 1 で示された同じコマンドを使用して、com.amazonaws..bedrock-agentcore 用の VPC インターフェースエンドポイントを作成します。
VPC Endpoint ENI の IP アドレスの取得
VPC エンドポイントによって作成された ENI のプライベート IP アドレスを取得します。これらの IP が ALB ターゲットグループのターゲットとなります。
ENI ID を取得する
aws ec2 describe-vpc-endpoints \
--vpc-endpoint-ids vpce-xxxxxxxxx \
--query "VpcEndpoints[0].NetworkInterfaceIds"
プライベート IP アドレスを取得する
aws ec2 describe-network-interfaces \
--network-interface-ids eni-aaaa eni-bbbb \
--query "NetworkInterfaces[].PrivateIpAddress"
ヘルスチェック付きの IP ターゲットグループを作成する
このステップは、パターン 2 を機能させるための重要な設定です。認証を必要としないヘルスチェックを持つ HTTPS ポート 443 の IP タイプのターゲットグループを作成します。
aws elbv2 create-target-group \
--name agentcore-vpce-tg \
--target-type ip \
--protocol HTTPS \
--port 443 \
--vpc-id vpc-xxxxxxxxx \
--health-check-protocol HTTPS \
--health-check-port 443 \
--health-check-path / \
--matcher HttpCode=200-499
*注記:このターゲットグループには追加費用はかかりませんが、関連するアプリケーションロードバランサ(Application Load Balancer)には時間課金および LCU(Load Balancer Capacity Unit)の請求が発生し、VPC インターフェースエンドポイントにも時間課金とデータ処理料金が適用されます。詳細は Elastic Load Balancing の価格設定 をご覧ください。
ヘルスチェックではパス「/」を使用し、マッチャーとして 200–499 を指定します。AgentCore は有効な API パスではないため「/」に対して 404 を返しますが、ALB は 200–499 の範囲内の応答を健全(healthy)とみなして受け入れます。これは、VPC エンドポイントが応答していることを確認することが目的であるためです。具体的なステータスコードは問題ありません。このアプローチでは、ヘルスチェックに認証は不要です。
ターゲットの登録
VPC エンドポイント ENI の IP アドレスをターゲットとして登録します:
aws elbv2 register-targets \
--target-group-arn \
--targets Id=10.0.1.100,Port=443 Id=10.0.2.200,Port=443
Create the HTTPS listener
Create an HTTPS listener on the ALB that forwards to the target group. The ALB handles TLS termination using your ACM certificate:
aws elbv2 create-listener \
--load-balancer-arn \
--protocol HTTPS \
--port 443 \
--certificates CertificateArn= \
--default-actions Type=forward,TargetGroupArn=
Attach AWS WAF
Associate an AWS WAF WebACL with the ALB, using the same approach described in Pattern 1, Step 4.
How authentication passes through the ALB
The ALB passes the Authorization header through without modification. Both SigV4 signatures and OAuth Bearer tokens reach AgentCore transparently.
For SigV4 (AWS SDK), point the SDK to the ALB endpoint URL. The SDK handles signing automatically:
import boto3
client = boto3.client(
"bedrock-agentcore",
endpoint_url="https://"
)
response = client.invoke_agent_runtime(
agentRuntimeArn="arn:aws:bedrock-agentcore:...",
payload='{"input": "hello"}'
)
For OAuth (browser or curl), pass the JWT as a Bearer token:
curl -X POST https:///runtimes//invocations \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"input": "hello"}'
注記: Amazon Cognito で client_credentials grant を使用する際、JWT には client_id クレームが含まれますが aud クレームは含まれません。allowedAudience の代わりに allowedClients(client_id と一致)を指定して AgentCore OAuth 認証者を設定してください。
パターン 2 のトレードオフ
側面
影響
レイテンシ
Lambda のレイテンシオーバーヘッドはなく、直接パススルーされます。
コスト
追加の計算コストは発生しません。
複雑性
構成要素が最小限で、ALB と VPC エンドポイントのみです。
柔軟性
リクエスト変換機能はありません。
直接アクセス用のバックドアを resou で閉じる
原文を表示
When you deploy generative AI agents with Amazon Bedrock AgentCore as production API endpoints, you might want to enforce web application firewall policies, rate limiting, protection against common web threats, or audit controls via AWS WAF.
AWS WAF integrates with Elastic Load Balancing Application Load Balancers (ALBs), Amazon CloudFront distributions, and Amazon API Gateway REST APIs. Amazon CloudFront is designed for caching and content delivery. Since agent invocations are real-time and dynamic, caching doesn’t apply. Amazon API Gateway adds its own authentication and request transformation layer, which can create a double-authentication problem with the built-in SigV4 and OAuth handling in AgentCore. That leaves an internet-facing ALB as the integration point: It passes headers through transparently, supports VPC-internal routing, and attaches directly to an AWS WAF WebACL. From there, you route traffic to AgentCore through a VPC Interface Endpoint for the Bedrock AgentCore data plane service.
This is where the challenge appears. ALBs require health checks to verify that backend targets are responsive. But AgentCore Runtime requires authentication, SigV4 or OAuth, on API calls, including health check requests. Standard ALB health checks send unauthenticated requests, so they fail out of the box. You need a way to make health checks work without credentials while still passing authenticated production traffic through to AgentCore.
This post shows you two architecture patterns that address this problem. Both use an internet-facing ALB with AWS WAF and route traffic through a VPC Interface Endpoint to AgentCore Runtime. Pattern 1 places an AWS Lambda proxy between the ALB and the VPC Endpoint, giving you full control over request transformation. Pattern 2 targets the VPC Endpoint ENI IP addresses directly from the ALB, removing the Lambda hop entirely. You also learn how to close the direct-access backdoor with a resource policy so that traffic flows through AWS WAF only. Both patterns have been tested end-to-end with SigV4 and OAuth (Amazon Cognito JWT) authentication.
Architecture overview
The two patterns share a common foundation. A client application sends an authenticated request, either a SigV4 signature or an OAuth Bearer token, to an internet-facing ALB. AWS WAF inspects the request before the ALB forwards it to VPC Endpoint ENIs on HTTPS port 443. AgentCore validates the authentication and routes the request to the runtime container on its internal port 8080. The difference between the patterns is what sits between the ALB and the VPC Endpoint.

High-level architecture, Client → AWS WAF → ALB → VPC Endpoint (PrivateLink) → AgentCore Runtime container
The architecture has four components:
- AWS WAF attaches to the ALB and provides rate limiting, SQL injection protection, XSS filtering, and bot control through managed rule groups like AWSManagedRulesCommonRuleSet.
- ALB is internet-facing with an HTTPS listener on port 443, routing traffic to VPC Endpoint ENI IP targets.
- VPC Interface Endpoint (com.amazonaws..bedrock-agentcore) provides private connectivity to AgentCore through PrivateLink.
- AgentCore Runtime is the managed container running your agent code, listening on internal port 8080 and supporting both SigV4 and OAuth authentication.
*Note: Use com.amazonaws..bedrock-agentcore (data plane) for Runtime invocations. There are three separate endpoint services: bedrock-agentcore (data plane for Runtime, Memory, Tools), bedrock-agentcore-control (control plane), and bedrock-agentcore.gateway (Gateway only). Using the wrong endpoint will not route to your Runtime.*
Prerequisites
To follow along with this walkthrough, you need:
- An AWS account with Amazon Bedrock AgentCore enabled.
- An AgentCore Runtime deployed (public or VPC mode).
- A VPC with public and private subnets across at least two Availability Zones.
- An AWS Certificate Manager (ACM) certificate in the same Region, for the ALB’s HTTPS listener.
- An Amazon Cognito User Pool (for the OAuth pattern) or AWS credentials (for the SigV4 pattern).
- Familiarity with ALB, VPC Endpoints, and AWS WAF.
The following sections describe two patterns for integrating AWS WAF with AgentCore. If you need request transformation, custom logging, or authentication translation between the ALB and AgentCore, start with Pattern 1. If you want the simplest architecture with the lowest latency and no additional components, skip to Pattern 2.
Pattern 1: ALB with Lambda proxy
In this pattern, a Lambda function sits behind the ALB and forwards requests, including the authentication header, to AgentCore through the VPC Endpoint. The Lambda function gives you a compute layer where you can transform requests, translate between authentication methods, or add custom logging before the request reaches AgentCore.

Pattern 1 architecture, Client (JWT) → AWS WAF → ALB → Lambda Proxy → VPC → VPC Endpoint → AgentCore Runtime (OAuth authorizer)
Choose Pattern 1 if you need:
- Request transformation, header manipulation, payload changes, or protocol translation.
- Custom logging or audit trails at the proxy layer.
- Translation between multiple authentication methods.
- An explicit compute layer between the ALB and backend (some security policies require this).
Create the VPC Endpoint
Create a VPC Interface Endpoint for the AgentCore data plane service in your private subnets:
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxxx \
--service-name com.amazonaws.us-east-1.bedrock-agentcore \
--vpc-endpoint-type Interface \
--subnet-ids subnet-aaaa subnet-bbbb \
--security-group-ids sg-xxxxxxxxx*Note: VPC Interface Endpoints incur hourly charges per Availability Zone plus data processing charges per GB. See VPC pricing.*
Configure the VPC Endpoint security group to allow inbound HTTPS (port 443) only from the ALB’s security group. This restricts access so that traffic routed through the ALB can reach the VPC Endpoint. For example:
aws ec2 authorize-security-group-ingress \
--group-id \
--protocol tcp \
--port 443 \
--source-group Create the Lambda proxy
The Lambda function receives requests from the ALB and forwards them to AgentCore through the VPC Endpoint. For OAuth, it passes the Authorization header (the Bearer token) through unchanged, along with the original request path and body, so the JWT reaches AgentCore as-is. For SigV4, the signature is bound to the original request host and becomes invalid after the request is forwarded to the VPC Endpoint, so the proxy re-signs the request using its own execution-role credentials.
The following Python snippet shows the core forwarding logic. The function reads the Authorization header from the ALB event, constructs the target URL using the VPC Endpoint DNS name, and forwards the request with the original headers and body intact. This forwarding path works as-is for OAuth Bearer tokens. SigV4 requests require the additional re-signing step, which is included in the accompanying repository.
import json
import urllib3
import os
http = urllib3.PoolManager()
VPCE_DNS = os.environ["VPCE_DNS_NAME"]
def handler(event, context):
path = event.get("path", "/")
headers = event.get("headers", {})
body = event.get("body", "")
method = event.get("httpMethod", "POST")
target_url = f"https://{VPCE_DNS}{path}"
resp = http.request(
method,
target_url,
headers={
"Authorization": headers.get("authorization", ""),
"Content-Type": headers.get("content-type", "application/json"),
},
body=body,
)
return {
"statusCode": resp.status,
"headers": {"Content-Type": "application/json"},
"body": resp.data.decode("utf-8"),
}For brevity, the preceding snippet focuses on the forwarding logic. The complete production-ready implementation, including SigV4 signing, query string handling, ALB health check responses, and structured error handling, is available in the accompanying GitHub repository.
*Note: The Lambda proxy incurs charges per request and for compute duration (GB-seconds). See AWS Lambda pricing.*
Configure ALB with Lambda target group
Create a Lambda target group, register the proxy function, and create an HTTPS listener on the ALB. The ALB handles TLS termination and forwards the decrypted request to the Lambda function.
*Note: Application Load Balancers incur hourly charges plus Load Balancer Capacity Unit (LCU) charges based on traffic. See Elastic Load Balancing pricing.*
Attach AWS WAF
Associate an AWS WAF WebACL with the ALB. A typical starting configuration includes AWSManagedRulesCommonRuleSet for protection against common web threats, a rate-based rule to throttle excessive requests per source IP, and AWSManagedRulesBotControlRuleSet if your agents are exposed to browser-based clients. You can add or remove managed rule groups based on your threat model. These are examples, not a prescriptive minimum.
*Note: AWS WAF incurs charges per WebACL per month, per rule, and per million requests inspected. See AWS WAF pricing.*
*Note: Lambda target groups don’t use path-based health checks. The ALB verifies the function is invocable by calling it directly, so no special health check configuration is needed.*
Pattern 1 trade-offs
Aspect
Impact
Latency
Adds 50–200 ms per request (Lambda cold start). Mitigate with provisioned concurrency.
Cost
Lambda invocation cost per request.
Complexity
Additional component to deploy, monitor, and maintain.
Flexibility
Full control over request/response transformation and custom logging.
*Note: The Lambda proxy adds approximately 50–200 ms of latency per request. For latency-sensitive workloads, consider Pattern 2, which removes this overhead.*
Pattern 2: ALB directly to VPC Endpoint
In this pattern, the ALB targets the VPC Endpoint ENI IP addresses directly on HTTPS port 443. There is no Lambda function and no Network Load Balancer. The ALB passes authentication headers through to AgentCore transparently. This architecture has fewer components and removes the Lambda proxy hop.

Pattern 2 architecture, Client (JWT or SigV4) → AWS WAF → ALB → VPC Endpoint ENIs (HTTPS 443) → AgentCore Runtime
Choose Pattern 2 if you want:
- A simpler architecture with fewer components.
- No request transformation between the ALB and AgentCore.
- Minimal latency with no additional hops.
- Your client application to handle SigV4 or OAuth signing directly.
Create the VPC Endpoint
Create a VPC Interface Endpoint for com.amazonaws..bedrock-agentcore in your private subnets, using the same command shown in Pattern 1, Step 1.
Retrieve the VPC Endpoint ENI IP addresses
Get the private IP addresses of the ENIs created by the VPC Endpoint. These IPs become the targets for your ALB target group.
# Get the ENI IDs
aws ec2 describe-vpc-endpoints \
--vpc-endpoint-ids vpce-xxxxxxxxx \
--query "VpcEndpoints[0].NetworkInterfaceIds"
# Get the private IPs
aws ec2 describe-network-interfaces \
--network-interface-ids eni-aaaa eni-bbbb \
--query "NetworkInterfaces[].PrivateIpAddress"Create an IP target group with a health check
This step is the key configuration that makes Pattern 2 work. Create an IP-type target group on HTTPS port 443 with a health check that doesn’t require authentication.
aws elbv2 create-target-group \
--name agentcore-vpce-tg \
--target-type ip \
--protocol HTTPS \
--port 443 \
--vpc-id vpc-xxxxxxxxx \
--health-check-protocol HTTPS \
--health-check-port 443 \
--health-check-path / \
--matcher HttpCode=200-499*Note: This target group is available at no additional cost, but the associated Application Load Balancer incurs hourly plus LCU charges, and the VPC Interface Endpoint incurs hourly and data processing charges. See Elastic Load Balancing pricing.*
The health check uses path / with a matcher of 200–499. AgentCore returns a 404 on / because it isn’t a valid API path, but the ALB accepts responses in the 200–499 range as healthy. This works because the goal is to verify that the VPC Endpoint is responding. The specific status code doesn’t matter. This approach requires no authentication for health checks.
Register the targets
Register the VPC Endpoint ENI IPs as targets:
aws elbv2 register-targets \
--target-group-arn \
--targets Id=10.0.1.100,Port=443 Id=10.0.2.200,Port=443Create the HTTPS listener
Create an HTTPS listener on the ALB that forwards to the target group. The ALB handles TLS termination using your ACM certificate:
aws elbv2 create-listener \
--load-balancer-arn \
--protocol HTTPS \
--port 443 \
--certificates CertificateArn= \
--default-actions Type=forward,TargetGroupArn=Attach AWS WAF
Associate an AWS WAF WebACL with the ALB, using the same approach described in Pattern 1, Step 4.
How authentication passes through the ALB
The ALB passes the Authorization header through without modification. Both SigV4 signatures and OAuth Bearer tokens reach AgentCore transparently.
For SigV4 (AWS SDK), point the SDK to the ALB endpoint URL. The SDK handles signing automatically:
import boto3
client = boto3.client(
"bedrock-agentcore",
endpoint_url="https://"
)
response = client.invoke_agent_runtime(
agentRuntimeArn="arn:aws:bedrock-agentcore:...",
payload='{"input": "hello"}'
)For OAuth (browser or curl), pass the JWT as a Bearer token:
curl -X POST https:///runtimes//invocations \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"input": "hello"}'*Note: When using the client_credentials grant in Amazon Cognito, the JWT contains a client_id claim but no aud claim. Configure the AgentCore OAuth authorizer with allowedClients (which matches client_id) instead of allowedAudience.*
Pattern 2 trade-offs
Aspect
Impact
Latency
No Lambda latency overhead, direct passthrough.
Cost
No additional compute cost.
Complexity
Minimal components, ALB + VPC Endpoint only.
Flexibility
No request transformation capability.
Closing the direct-access backdoor with resou
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み