Amazon ECS で Amazon Bedrock AgentCore Identity を使用して AI エージェントを保護
AWS は Amazon Bedrock AgentCore Identity を活用し、Amazon ECS で動作する AI エージェント向けの OAuth 2.0 認証コードグラント実装とセッションバインディングの具体的な手法を公開した。
キーポイント
ECS 環境におけるセキュリティ課題への対応
Amazon ECS や EKS などの計算プラットフォームで AI エージェントを実行する際の、セッションバインドエンドポイントの構築とワークロードアクセストークンのライフサイクル管理という具体的な課題に焦点を当てている。
OAuth 2.0 と OIDC を活用した厳格な認証フロー
ユーザーの身元確認(OIDC)と権限付与(OAuth 2.0)を組み合わせ、Authorization Code Grant(3 段階 OAuth)を採用することで、エージェントがユーザーに代わって行動する際の同意プロセスと監査証跡を確立している。
CSRF 攻撃防止と最小権限の原則の実装
セッションバインディングにより CSRF やブラウザ置換攻撃を防ぎ、各ユーザーセッションにスコープされたトークンを発行することで、最小権限の原則に基づいたセキュリティを担保している。
影響分析・編集コメントを表示
影響分析
本記事は、生成 AI エージェントが実環境(プロダクション)で安全に運用されるための具体的な認証・認可アーキテクチャを示しており、特に AWS ECS 上でエージェントをデプロイする開発者にとって即座に適用可能な実践的なガイドラインとなる。これにより、AI エージェントのセキュリティリスク管理が抽象論から具体的な実装レベルへと移行し、組織における AI の信頼性とコンプライアンス対応が強化される。
編集コメント
AI エージェントの実用化において、単なる機能実装だけでなく、認証と認可のセキュリティ基盤をどう設計するかが最大の課題の一つです。本記事は AWS の公式ブログとして、ECS 環境における具体的な実装パターンを提供しており、開発者がすぐに参照・適用できる貴重なリソースと言えます。
本番環境における AI エージェントは、外部サービスへの安全なアクセスを必要とします。スタンドアロンサービスとして利用可能な Amazon Bedrock AgentCore Identity は、AI エージェントが Amazon ECS、Amazon EKS、AWS Lambda といった計算プラットフォーム上で動作する場合や、オンプレミス環境で動作する場合にかかわらず、外部サービスへのアクセス方法を保護します。
以前の 投稿 では、AI エージェント向けの AgentCore Identity による資格情報管理について取り上げました。ECS などの計算環境上でエージェントを実行する際、2 つの重要な問いが生じます。すなわち、「アプリケーション所有のセッションバインディングエンドポイントをどのように構築するか」および「ワークロードアクセストークンのライフサイクルをどのように管理するか」という点です。
本投稿では、Amazon ECS 上で安全なセッションバインディングとスコープ付きトークンを用いた Authorization Code Grant(3 レイヤー OAuth)の実装を行います。本稿は以下の機能を持つ動作実装を提供します:
- CSRF およびブラウザの乗り換え攻撃を防ぐための安全なセッションバインディング
- 最小権限の原則に従い、各ユーザーセッションごとにスコープが設定された認証トークン
- エージェントワークロードとセッションバインディングサービスとの間の関心の分離
OAuth 2.0 と OIDC を用いた認証と認可
本ソリューションでは、OAuth 2.0(RFC 6749)および OpenID Connect(OIDC)を利用します。OIDC はユーザーの身元(誰であるか)を認証し、OAuth 2.0 はその行動(何ができるか)に対する権限付与を行います。
ここでは、ユーザー委任アクセスのための「認可コードグラント」に焦点を当てます。ユーザーはアイデンティティプロバイダで認証を行い、同意を与えます。その後、アプリケーションは認可コードと交換してアクセストークンを取得し、監査証跡を作成します。このフローでは、ユーザーがアイデンティティプロバイダで認証し、エージェントが代わりに特定のリソースにアクセスするための同意を与えます。アプリケーションは生成された認可コードをスコープ付きのアクセストークンと交換し、Amazon Bedrock AgentCore Identity がこれをトークン vault に保存します。各トークンは明示的な同意を持つ特定のユーザーアイデンティティに紐付けられているため、本ソリューションではユーザー認証からエージェントアクションに至るまで監査可能な連鎖を維持します。
認可コードグラントは、ユーザーの代わりに動作するアジェンティックワークロードに適しています。これは、エージェントが行動する前にユーザーの同意を得られること、承認リクエストを開始したユーザーと同意を与えたユーザーが同一であることを検証するセッションバインディング、およびユーザーが承認した権限のみをエージェントに制限するスコープ付き委任を提供するためです。
コールバック URL とセッションバインディング URL
この文脈では、Authorization Code Grant フローはしばしば混同される 2 つの URL を使用します:
- コールバック URL: AgentCore Identity で OAuth クライアントを作成する際に自動的に生成されます。これは AgentCore Identity を指し、ユーザー認証後に認可コードが送信されるリダイレクト先として、認可サーバーに登録する必要があります。
- セッションバインディング URL: 認証されたユーザーと OAuth フロー間のセッションバインディングを完了させる、顧客が管理するサービスへの戻り先を示す URL です。このエンドポイントは顧客によって実装・ホストされます。
ソリューションの概要
このアーキテクチャ図は、AgentCore Identity が Amazon ECS 上のセルフホスト型 AI エージェントをどのように保護するかを示しています。このウォークスルーでは Microsoft Entra ID をアイデンティティプロバイダーとして使用しますが、他の OIDC 準拠プロバイダーもサポートされています。本ウォークスルーの完全なソースコードと前提条件は、添付の GitHub リポジトリ で利用可能です。
本ソリューションは、アプリケーションロードバランサーの背後に Amazon ECS で 2 つのサービスを展開します。Agentic Workload は AI エージェントを実行し、ユーザーリクエストを処理します。Session Binding Service は OAuth のコールバックを処理して、ユーザーセッションとサードパーティのアクセストークンをリンクさせます。両方のサービスは、Amazon Bedrock AgentCore Identity を使用して、OIDC を経由して入力されるユーザーの認証および、その代わりにアウトバウンドアクションを実行する権限付与を行います。図中の番号付き注釈は、以下の説明に対応しています。

- 入力認証とトラフィックルーティング:リクエストは Amazon Application Load Balancer (ALB) に到達し、ALB の組み込み OIDC 認証フローを通じてユーザーが認証されます。トラフィックは AWS Certificate Manager から取得した証明書を使用した HTTPS で暗号化され、Amazon Route 53 パブリックホストドメインのエイリアス A レコードがロードバランサーへトラフィックをルーティングします。OIDC を介してユーザーを認証した後、ALB はリクエストを Amazon ECS クラスターに転送します。ALB は、JWT 形式でユーザーのクレームを含む
x-amzn-oidc-dataヘッダーを注入し、subフィールドがユーザーを一意に識別します。
- エージェントワークロード:Agentic Workload は、sessionId とメッセージを受け付ける
/invocationsエンドポイントを備えた FastAPI サーバーを公開しています。FastAPI サーバーはこれらを Strands Agents で構築されたエージェントに渡します。サーバーはエージェントフレームワークとは独立してリクエストを処理するため、LangChain や他のエージェント SDK も使用可能です。エージェントは Amazon Bedrock 上の大規模言語モデル (LLM) を呼び出しますが、他のモデルプロバイダーも利用できます。エージェントはセッション状態を Amazon S3 バケットに保存し、ユーザー間のセッションを分離するためにsubクレームをキープレフィックスとして使用します。また、エージェントには GitHub でユーザーの代わりにアクションを実行するためのツールがあり、これにはユーザーの OAuth アクセストークンが必要です。
- AgentCore Identity を用いた出力認証:エージェントが GitHub などのサードパーティサービスでユーザーの代わりに行動する必要がある場合、AgentCore Identity を通じて OAuth アクセストークンを要求します。有効なトークンが存在しない場合、AgentCore Identity は認可コード付与フローを開始し、ユーザーにアクセス権限の付与を求めます。
- OAuth コールバック処理:ユーザーがアクセス権限を付与した後、Session Binding Service が AgentCore Identity を介して正しいユーザーセッションへの認証バインディングを行うことで、OAuth フローを完了します。
- ユーザーインターフェース:エージェントワークロードをホストする FastAPI サーバーは
/docsエンドポイントを公開しており、これは OpenAPI 仕様を対話形式の HTML ページとしてレンダリングします。エンドユーザーはこのページを通じてエージェントと対話し、デモンストレーション用の最小限の UI が提供されます。
Amazon CloudWatch がログをキャプチャし、専用の S3 バケットがロードバランサーおよびデータバケットの両方のアクセスログを保存します。ECS は Amazon ECR からコンテナイメージを取得します。一般的な Web 攻撃に対する基本的な保護を提供するため、一連の AWS WAF ルールがロードバランサーに付与されます。Amazon KMS カスタマー管理キー (CMK) がデータを暗号化しますが、アクセスログ用バケットは例外であり、こちらは Amazon S3 マネージド暗号化 (SSE-S3) を必要とします。
Amazon Bedrock AgentCore Identity: 認可コードグラント
このチュートリアルでは、ALB を認証に使用し、専用のセッションバインディングサービスを持ち、AgentCore SDK およびランタイムの代わりに直接 API 呼び出しを行うセルフホスト型アーキテクチャ向けに、一般的な AgentCore Identity セッションバインディングフロー を適応させたものです。
シーケンス図は、AgentCore Identity のワークロードアイデンティティ、ワークロードアクセストークン、および OAuth 2.0 クレデンシャルプロバイダ が、ユーザーに代わってエージェントに対して OAuth トークンを安全に提供するためにどのように連携するかを示しています。このフローは、認証済みユーザーがまだエージェントにリソースへのアクセスを許可していないことを前提としており、AgentCore Identity トークン vault 内に有効なトークンは存在しない状態です。
##
- 認証されたユーザーがエージェントワークロードに対してリクエストを送信します。エージェントワークロードは、ALB署名付きJWT(x-amzn-oidc-data ヘッダー)内の sub クレームからユーザーIDを抽出し、ユーザーを識別します。
- エージェントワークロードは、GetWorkloadAccessTokenForUserId API を呼び出し、userId と workloadName を渡して、このユーザーにスコープされたエージェントのアイデンティティを表すワークロードアクセストークンを取得します。
- AgentCore Identity は、ワークロードアクセストークンをエージェントワークロードに返します。
- エージェントワークロードは、GetResourceOauth2Token API を呼び出し、ワークロードアクセストークン、設定された OAuth 2.0 クレデンシャルプロバイダーのプロバイダー名、セッションバインディング URL(callbackUrl パラメータを参照)、および必要なスコープ(例:GitHub の read:user スコープ)を渡します。これにより、サードパーティサービス(この場合は GitHub)の OAuth トークンを要求します。
- このユーザーに対して有効なトークンが存在しないため、AgentCore Identity は、OAuth 2.0 認証プロセス中の後続のリクエストとレスポンス全体にわたって承認フローの状態を追跡する sessionURI を作成します。
- AgentCore Identity は、承認 URL とセッション URI をワークロードに返します。
- エージェントワークロードは、ユーザーに対してアクセスの承認を促すために、承認 URL をユーザーに返します。
- ユーザーは承認 URL をクリックし、サードパーティプロバイダーの同意画面でエージェントへの権限付与を行います。
- 認証サーバーは、承認コードを AgentCore Identity に送信します。
- AgentCore Identity は、セッション URI を追加したセッションバインディング URL を介してユーザーをリダイレクトし、セッションバインディングサービスへルーティングします。
- ユーザーのブラウザは、セッションバインディング URL を経由してセッションバインディングサービスへのリダイレクトに従います。ALB は x-amzn-oidc-data ヘッダーに JWT を注入します。
- セッションバインディングサービスは、CompleteResourceTokenAuth API を呼び出し、セッション URI とユーザー ID(JWT から抽出)を渡して、完了した承認を正しいユーザーセッションにバインドします。成功した場合、承認が正常に行われたことを確認する静的なアプリケーション所有の HTML ページを返します。
- AgentCore Identity は、認証サーバーと承認コードを交換し、OAuth2 アクセストークンを取得します。
- 認証サーバーは OAuth2 アクセストークンを返します。
- AgentCore Identity は、トークン vault にトークンを保存します。
- AgentCore Identity は、セッションバインディングサービスに成功を通知します。
- セッションバインディングサービスは、ユーザーに対して「承認完了」を表示します。
後続のリクエストにおいて、ユーザーが再承認を行う必要があるかどうかは、認証サーバーが発行した資格情報によります。AgentCore Identity は、アクセストークンとリフレッシュトークン(利用可能な場合)の両方をトークン vault に保存します。リフレッシュトークンが存在する場合(GitHub でユーザーからサーバーへのトークンの有効期限切れが有効になっている場合など)、AgentCore Identity は元のトークンが期限切れになると自動的にリフレッシュトークンを使用して新しいアクセストークンを取得し、ユーザーに再度プロンプトを表示しません。リフレッシュトークンが発行されず、アクセストークンが期限切れになった場合は、ユーザーに再承認を求められます。なお、トークンはプロバイダー側で取り消される場合もあります。そのような場合には、forceAuthentication: true を設定することで、新しい認証フローを強制します。
セッションバインディング:
セッションバインディングは、2 つのセキュリティ脅威から保護します:
クロスサイトリクエストフォージェリ (CSRF): 攻撃者が自分の OAuth トークンを被害者の ID に紐付けようとし、被害者のエージェントが知らないうちに攻撃者のリソースにアクセスすることで、データの窃取や注入を可能にします。
ブラウザ置換攻撃: 攻撃者が被害者に代わって同意させるように仕向け、被害者の OAuth トークンを攻撃者の ID に紐付けることで、攻撃者に被害者のリソースへの直接アクセス権を与えてしまいます。
セッションバインディングは、エージェントワークロードのユーザー ID とセッションバインディングサービスのユーザー ID が一致することを保証し、両方の ID を認証チェーンを通じて暗号学的に検証することで、これらの攻撃を防止します。
AgentCore Identity はまた、GetResourceOauth2Token API にオプションの customState パラメータをサポートしており、OAuth 2.0 仕様に推奨されている通り、CSRF 攻撃からコールバックエンドポイントを保護するために暗号学的にランダムな nonce を渡すために使用できます。
AWS ALB と Microsoft Entra ID を使用して GetWorkloadAccessTokenForUserId を使用する理由
ワークロードアクセストークンを取得するための推奨 API は GetWorkloadAccessTokenForJWT です。しかし、このソリューションでは代わりに GetWorkloadAccessTokenForUserId を使用しています。
GetWorkloadAccessTokenForJWT には、ランタイムで発行元の公開署名鍵に対して検証可能な署名を持つ動的に有効な JWT と、アプリケーションの aud クレームが一致するトークンが必要です。Microsoft Entra ID からこのようなトークンを取得するには、OIDC 認可リクエストのスコープにアプリケーション ID を含める必要があります。詳細については AgentCore Microsoft インバウンドドキュメント を参照してください。
*しかし、これは AWS ALB の OIDC フローとは互換性がありません。*
OIDC ハンドシェイクの一部として(ALB OIDC ドキュメントを参照)、ALB はアクセス トークンを Entra の UserInfo エンドポイントに送信し、認証されたユーザーのクレームを取得します。これは ALB の認証フローにおける必須ステップです。この UserInfo エンドポイントは Microsoft Graph(https://graph.microsoft.com/oidc/userinfo)上でホストされており、Microsoft Graph にスコープされたトークンしか受け付けません。スコープにアプリケーション ID を含めると、生成されるアクセス トークンのオーディエンスはあなたのアプリケーションとなり、UserInfo エンドポイントは 401 で拒否し、ALB は 561 を返します。
もしスコープからアプリケーション ID を削除すると、Entra はデフォルトでアクセス トークンのオーディエンスを Microsoft Graph(00000003-0000-0000-c000-000000000000)に設定します。ALB のハンドシェイクは成功しますが、生成された JWT は AgentCore で動的に検証できず、GetWorkloadAccessTokenForJWT では使用できません。
このソリューションでは、ALB が Graph スコープのトークンを使用してハンドシェイクを完了します。ALB は、ユーザー情報エンドポイントからのユーザーの主張(claims)を含む x-amzn-oidc-data ヘッダーに、ALB 署名付き JWT を転送します。これには、認証されたユーザーを一意に識別する sub クレームも含まれています。私たちは、AWS が公開した署名鍵を使用してこの ALB 署名付き JWT を検証し、sub を抽出して GetWorkloadAccessTokenForUserId に渡します。
実装
完全なコードは GitHub リポジトリ でご覧ください。
ワークロードアクセストークンの取得
サーバーは JWT の sub クレームからユーザー ID を抽出し、AgentCore Identity からワークロードアクセストークンを要求します。その後、サーバーはこのトークン、セッション ID、およびメッセージを使用して、ユーザーに代わってエージェントを呼び出します。ここでいうセッション ID は、認証フローからの OAuth セッション URI ではなく、エージェントの会話セッションを指す点にご注意ください。
@router.post("/invocations")
async def invoke_agent(
request: InvocationRequest,
user_id: str = Depends(get_current_user),
settings: Settings = Depends(get_settings),
agent_service: AgentService = Depends(get_agent_service),
) -> StreamingResponse:
"""ストリーミングレスポンスでエージェントを呼び出します。"""
try:
agentcore = boto3.client("bedrock-agentcore", region_name=settings.identity_aws_region)
response = agentcore.get_workload_access_token_for_user_id(
workloadName=settings.workload_identity_name, us
原文を表示
AI agents in production require secure access to external services. Amazon Bedrock AgentCore Identity, available as a standalone service, secures how your AI agents access external services whether they run on compute platforms like Amazon ECS, Amazon EKS, AWS Lambda, or on-premises.
An earlier post covered AgentCore Identity credential management for AI agents. Running agents on compute environments like ECS raises two questions: How to build an application-owned Session Binding endpoint, and how to manage workload access token lifecycle?
This post implements Authorization Code Grant (3-legged OAuth) on Amazon ECS with secure session binding and scoped tokens. This post provides a working implementation with:
- Secure session binding that prevents CSRF and browser-swapping attacks
- Auth tokens scoped to each user session, following least-privilege principles
- Separation of concerns between the agent workload and session binding service
Authentication and authorization with OAuth 2.0 and OIDC
This solution uses OAuth 2.0 (RFC 6749) and OpenID Connect (OIDC). OIDC authenticates users (who they are), and OAuth 2.0 authorizes their actions (what they can do).
We focus on the Authorization Code Grant for user-delegated access. The user authenticates with an identity provider and grants consent. The application then exchanges an authorization code for an access token, which creates an audit trail.In this flow, the user authenticates with an identity provider and grants consent for the agent to access specific resources on their behalf. The application exchanges the resulting authorization code for a scoped access token which Amazon Bedrock AgentCore Identity secures in its token vault. Because each token is bound to a specific user identity with explicit consent, the solution maintains an auditable chain from user authentication through to agent action.
The Authorization Code Grant is suited for agentic workloads that act on behalf of users because it provides user consent before the agent can act, session binding that verifies the user who initiated the authorization request is the same user who granted consent, and scoped delegation that limits the agent to only the permissions the user approved.
Callback URL vs. session binding URL
In this context, the Authorization Code Grant flow uses two URLs that are often confused:
- Callback URL: Automatically generated when creating an OAuth client in AgentCore Identity. It points to AgentCore Identity and must be registered with the Authorization Server as the redirect target where the authorization code is sent after user authentication.
- Session Binding URL: The URL pointing back to a customer-managed service that completes the session binding between the authenticated user and the OAuth flow. This endpoint is implemented and hosted by the customer.
Solution overview
This architecture diagram shows how AgentCore Identity secures a self-hosted AI agent on Amazon ECS. This walkthrough uses Microsoft Entra ID as the identity provider, but other OIDC-compliant providers are supported. The complete source code and prerequisites for this walkthrough are available in the accompanying GitHub repository.
The solution deploys two services on Amazon ECS behind an Application Load Balancer. The Agentic Workload runs the AI agent and handles user requests. The Session Binding Service processes OAuth callbacks to link user sessions with third-party access tokens. Both services use Amazon Bedrock AgentCore Identity to authenticate users inbound via OIDC and authorize outbound actions on their behalf. The numbered annotations in the diagram correspond to the following descriptions.

- Inbound authentication and traffic routing: Requests arrive at an Amazon Application Load Balancer (ALB), which authenticates the user through the ALB’s built-in OIDC authentication flow. Traffic is encrypted with HTTPS using a certificate from AWS Certificate Manager, and an alias A record in an Amazon Route 53 public hosted zone routes traffic to the load balancer. After authenticating the user through OIDC, the ALB forwards the request to the Amazon ECS cluster. The ALB injects an x-amzn-oidc-data header containing the user’s claims in JWT format, with the sub field uniquely identifying the user.
- Agentic workload: The Agentic Workload exposes a FastAPI server with an /invocations endpoint that accepts a sessionId and message. The FastAPI server passes these to an agent built with Strands Agents. You can also use LangChain or other agent SDKs since the server handles requests independently of the agent framework. The agent calls a large language model (LLM) on Amazon Bedrock, but other model providers work, too. The agent stores session state in an Amazon S3 bucket and it uses the user’s sub claim as a key prefix to isolate sessions between users. The agent also has tools to perform actions on the user’s behalf in GitHub, which requires the user’s OAuth access token.
- Outbound authentication with AgentCore Identity: When the agent needs to act on the user’s behalf in a third-party service like GitHub, it requests an OAuth access token through AgentCore Identity. If no valid token exists, AgentCore Identity initiates an Authorization Code Grant flow, prompting the user to authorize access.
- OAuth callback processing: After the user authorizes access, the Session Binding Service completes the OAuth flow by binding the authorization to the correct user session via AgentCore Identity.
- User interface: The FastAPI server that hosts the agentic workload exposes a /docs endpoint, which renders the OpenAPI specification as an interactive HTML page. The end user interacts with the agent through this page, which provides a minimal UI for demonstration
Amazon CloudWatch captures logs, and a dedicated S3 bucket stores access logs for both the load balancer and the data bucket. ECS pulls container images from Amazon ECR. A set of basic AWS WAF rules is attached to the load balancer to provide baseline protection against common web exploits. An Amazon KMS customer managed key (CMK) encrypts data, except for the access logs bucket, which requires Amazon S3 managed encryption (SSE-S3).
Amazon Bedrock AgentCore Identity: Authorization Code Grant
This walkthrough adapts the general AgentCore Identity session binding flow for a self-hosted architecture using ALB for authentication, a dedicated Session Binding Service, and direct API calls instead of the AgentCore SDK and Runtime.
The sequence diagram shows how AgentCore Identity’s workload identity, workload access tokens, and OAuth 2.0 credential provider work together to securely provide OAuth tokens to the agent on behalf of a user. This flow assumes the authenticated user has not yet authorized the agent to access their resources, meaning no valid token exists in the AgentCore Identity Token Vault.
##
- An authenticated user sends a request to the agentic workload. The agentic workload extracts the user ID from the sub claim in the ALB-signed JWT (x-amzn-oidc-data header) to identify the user.
- The agentic workload calls the GetWorkloadAccessTokenForUserId API, passing the userId and workloadName, to obtain a workload access token that represents the agent’s identity scoped to this user.
- AgentCore Identity returns the workload access token to the agentic workload.
- The agentic workload calls the GetResourceOauth2Token API, passing the workload access token, the provider name of the configured OAuth 2.0 credential provider, a session binding URL (see callbackUrl parameter), and the required scopes, for instance the read:user scope of GitHub. This requests an OAuth token for the third-party service (in this case, GitHub).
- Because no valid token exists for this user, AgentCore Identity creates a sessionURI that tracks the authorization flow state across the subsequent requests and responses during the OAuth 2.0 authentication process.
- AgentCore Identity returns an authorization URL and session URI to the workload
- The agentic workload returns the authorization URL to the user, prompting them to authorize access.
- The user clicks the authorization URL and grants the agent permission in the third-party provider’s consent screen.
- The Authorization Server sends the authorization code to AgentCore Identity.
- AgentCore Identity redirects the user to the Session Binding URL with the session URI appended, routing them to the Session Binding Service.
- The user’s browser follows the redirect to the Session Binding Service via the Session Binding URL. The ALB injects the JWT in the x-amzn-oidc-data header.
- The Session Binding Service calls the CompleteResourceTokenAuth API with the session URI and user ID (extracted from the JWT), binding the completed authorization to the correct user session. On success, it returns a static application owned HTML page confirming the authorization was successful.
- AgentCore Identity exchanges the authorization code with the Authorization Server for an OAuth2 access token.
- The Authorization Server returns the OAuth2 access token.
- AgentCore Identity stores the token in the Token Vault.
- AgentCore Identity returns success to the Session Binding Service.
- The Session Binding Service displays “Authorization complete” to the user.
On subsequent requests, whether the user needs to re-authorize depends on the credentials the authorization server issued. AgentCore Identity stores both access tokens and refresh tokens (when available) in the Token Vault. When a refresh token is present — as with GitHub when User-to-server token expiration is enabled — AgentCore Identity automatically uses it to obtain a new access token once the original expires, without prompting the user again. If no refresh token was issued and the access token expires, the user will be prompted to re-authorize. Note that tokens can also be revoked on the provider side; in such cases, setting forceAuthentication: true forces a fresh authentication flow.
Session binding:
Session binding protects against two security threats:
Cross-Site Request Forgery (CSRF): An attacker attempts to bind their own OAuth token to the victim’s identity, causing the victim’s agent to unknowingly access the attacker’s resources, enabling data exfiltration and injection.
Browser Swapping Attack: An attacker tricks the victim into consenting on their behalf, binding the victim’s OAuth token to the attacker’s identity, granting the attacker direct access to the victim’s resources.
Session binding prevents both attacks by ensuring that the user ID at the agent workload matches the user ID at the Session Binding Service, with both identities cryptographically verified through the authentication chain.
AgentCore Identity also supports an optional customState parameter in the GetResourceOauth2Token API that can be used to pass a cryptographically random nonce to protect your callback endpoint against CSRF attacks, as recommended by the OAuth 2.0 specification.
Why we use GetWorkloadAccessTokenForUserId with AWS ALB and Microsoft Entra ID
The recommended API for obtaining a workload access token is GetWorkloadAccessTokenForJWT. This solution uses GetWorkloadAccessTokenForUserId instead.
GetWorkloadAccessTokenForJWT requires a dynamically validatable JWT whose signature can be verified at runtime against the issuer’s published signing keys, and whose aud claim matches your application. To obtain such a token from Microsoft Entra ID, you must include your Application ID in the scope of the OIDC authorization request, see the AgentCore Microsoft Inbound documentation for details.
*However, this is incompatible with the AWS ALB OIDC flow.*
As part of its OIDC handshake (see ALB OIDC documentation), the ALB sends the access token to Entra’s UserInfo endpoint to retrieve the authenticated user’s claims which is a mandatory step in the ALB’s authentication flow. This UserInfo endpoint is hosted on Microsoft Graph (https://graph.microsoft.com/oidc/userinfo), and it only accepts tokens scoped to Microsoft Graph. When you include your Application ID in the scope, the resulting access token has your application as the audience, the UserInfo endpoint rejects it with a 401 and the ALB returns a 561.
If you remove your Application ID from the scope, Entra defaults the access token audience to Microsoft Graph (00000003-0000-0000-c000-000000000000). The ALB handshake succeeds but the resulting JWT cannot be dynamically validated by AgentCore. It is unusable with GetWorkloadAccessTokenForJWT.
This solution: The ALB completes its handshake using the Graph-scoped token. The ALB forwards an ALB-signed JWT in the x-amzn-oidc-data header containing the user’s claims from the UserInfo endpoint, including a sub claim that uniquely identifies the authenticated user. We validate this ALB-signed JWT using AWS’s published signing keys, extract the sub, and pass it to GetWorkloadAccessTokenForUserId.
Implementation
View the complete code GitHub repository.
Obtaining the Workload Access Token
The server extracts the user ID from the JWT’s sub claim and requests a workload access token from AgentCore Identity. The server then uses this token, the session ID, and the message to invoke the agent on behalf of the user. Note that session ID here refers to the agent’s conversation session, not the OAuth session URI from the authorization flow.
@router.post("/invocations")
async def invoke_agent(
request: InvocationRequest,
user_id: str = Depends(get_current_user),
settings: Settings = Depends(get_settings),
agent_service: AgentService = Depends(get_agent_service),
) -> StreamingResponse:
"""Invoke agent with streaming response."""
try:
agentcore = boto3.client("bedrock-agentcore", region_name=settings.identity_aws_region)
response = agentcore.get_workload_access_token_for_user_id(
workloadName=settings.workload_identity_name, us
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み