11月7日、AWSが「Govern AI agent access with Okta Cross App Access and Amazon Bedrock AgentCore – Part 1」と題した記事を公開した。記事の中心にあるのは「AIエージェントが誰の代わりに動いているか」という問題意識だ。チケット更新や顧客レコード参照を行うエージェントは、特定ユーザーの代理として動作する。しかし従来のOAuthコンセントや共有サービスアカウントでは、「どのエージェントが、どのユーザーの代わりに、どのアプリにアクセスできるか」を一元管理する手段がなかった。この記事が提示するのは、IDトークン・ID-JAG・アクセストークンの3段階トークンチェーンによってユーザー委任を厳密に制御するアーキテクチャだ。
3本のトークンチェーン
このソリューションの核心は、1リクエストに3種類のトークンを連携させる設計にある。
- IDトークン:「このユーザーは誰か」をOIDCで証明
- ID-JAG(Identity Assertion JWT Authorization Grant):「このエージェントがこのユーザーの代理として行動することをOktaが認可した」という決定を表すトークン(RFC 8693に基づくトークン交換)。単回使用・5分有効
- アクセストークン:リソース(MCPサーバー)が受け付けるトークン。ユーザーとエージェント双方の名前とユーザーのグループ情報を含む
リクエストの流れは以下のとおりだ:
- ユーザーがWebフロントエンド(BFF)にOIDCでサインイン
- BFFがユーザーのIDトークンをOktaのorg認可サーバーでID-JAGに交換(エージェントとして認証)
- BFFがID-JAGをベアラートークンとしてAgentCore runtimeのエージェントを呼び出し
- runtimeがAgentCore Identityからワークロードアクセストークンを取得し、エージェントコードに渡す(このトークンはAWS内部にとどまる)
- エージェントがAgentCore Identityにアクセストークンを要求。AgentCore IdentityがID-JAGをリソース側のOkta認可サーバーでRFC 7523形式のJWT認可グラントとして引き換え
- エージェントがそのトークンでMCPサーバーを呼び出し
解決したい問題:従来アプローチの限界
アーキテクチャの背景にある問題意識を整理しておく。従来のアプローチ——アプリごとのOAuthコンセント、共有サービスアカウント——では「どのエージェントが、どのユーザーの代わりに、どのアプリケーションにアクセスできるか」を一元管理する手段がなかった。
この記事が提示するアーキテクチャは、OktaをガバナンスプレーN、Amazon Bedrock AgentCoreを実行プレーンとして分離した設計だ。
- Okta Cross App Access(XAA):エージェントをOktaに登録し、管理者がアクセス可能なアプリを承認。ユーザーのアクセス権を剥奪してから約1秒以内に新規リクエストを拒否、発行済みトークンは5分以内に失効する
- Amazon Bedrock AgentCore Identity:OktaのJWT認可グラントを引き受け、エージェントコードに認証情報を渡すことなく短命アクセストークンを生成。エンドツーエンド約30秒のリクエストに対し、AgentCore Identityが追加するレイテンシは約0.6秒
実装上の重要ポイント
Okta側の設定
カスタム認可サーバー(audience: api://task-manager)にxaa:read・xaa:writeスコープを作成し、アクセストークンにグループクレームを付与する。ID-JAGリクエストにopenidやprofileなどのOIDCスコープを含めるとinvalid_scopeで拒否されるため、カスタムスコープのみを指定する必要がある。
POST /oauth2/v1/token HTTP/1.1
Host: YOUR-ORG.okta.com
Authorization: Basic <the agent's client ID and secret>
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
&subject_token=<the user's ID token>
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&audience=https://YOUR-ORG.okta.com/oauth2/YOUR-CUSTOM-AS-ID
&scope=xaa:read xaa:write
AgentCore Identityのクレデンシャルプロバイダー設定
control = boto3.client("bedrock-agentcore-control")
provider = control.create_oauth2_credential_provider(
name="okta-xaa-obo",
credentialProviderVendor="CustomOauth2",
oauth2ProviderConfigInput={"customOauth2ProviderConfig": {
"oauthDiscovery": {"discoveryUrl": f"{OKTA_ORG}/oauth2/{CUSTOM_AS_ID}/.well-known/openid-configuration"},
"clientId": AGENT_CLIENT_ID,
"clientSecret": AGENT_CLIENT_SECRET,
"clientAuthenticationMethod": "CLIENT_SECRET_BASIC",
"onBehalfOfTokenExchangeConfig": {"grantType": "JWT_AUTHORIZATION_GRANT"},
}},
)
Oktaは発行したID-JAGのclient_idとクレデンシャルプロバイダーのclient_idを照合するため、Oktaエージェントごとに個別のプロバイダーが必要だ。別エージェントのID-JAGを別プロバイダーで引き換えようとすると「The 'client_id' in the JWT Bearer Grant must match the 'client_id' used to authenticate the client」で拒否される。
ワークロードアクセストークンの取得
記事中では実装上の重要な注意点として、ワークロードアクセストークンはリクエストヘッダーではなく**BedrockAgentCoreContextから取得する**必要があることが強調されている。
from bedrock_agentcore.runtime import BedrockAgentCoreContext
identity = boto3.client("bedrock-agentcore")
def okta_access_token() -> str:
workload_token = BedrockAgentCoreContext.get_workload_access_token()
return identity.get_resource_oauth2_token(
workloadIdentityToken=workload_token,
resourceCredentialProviderName="okta-xaa-obo",
scopes=["xaa:read", "xaa:write"],
oauth2Flow="ON_BEHALF_OF_TOKEN_EXCHANGE",
)["accessToken"]
AgentCore Identityはアクセストークンをトークンヴォールトにキャッシュするため、同一リクエスト内の2回目の呼び出しは中央値58ミリ秒で返る。ID-JAGが単回使用であっても、2つ目のMCPサーバー向けに再度引き換える必要はない。
前提条件と所要時間
| 項目 | 使用環境 |
|---|---|
| AWSアカウント(Bedrock AgentCore + Claude) | US West (Oregon) |
| Cross App AccessおよびAPI Access Managementを有効にしたOktaオルグ | Okta Integrator Free Planオルグ |
| Python / AWS CLI / boto3 / AgentCore CLI・SDK | Python 3.11、AWS CLI v2、boto3 1.43、AgentCore CLI 0.31.1、SDK 1.24.1 |
ウォークスルーの所要時間は約1時間。ベースとなるサンプルコードはGitHubのAgentCoreサンプルリポジトリの08-okta-xaa-delegation-chainとして公開されている。
なお本記事はPart 1であり、Part 2ではAmazon Bedrock AgentCore GatewayとCedarポリシー、Amazon EKS上の第2エージェント、Amazon CloudWatchによる監査証跡を扱う予定だ。
詳細はGovern AI agent access with Okta Cross App Access and Amazon Bedrock AgentCore – Part 1を参照していただきたい。