0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Bedrock AgentCore Runtimeの認証を「SigV4とJWTで使い分け」てみた

0
Posted at

本記事では、Amazon Bedrock AgentCore Runtime の認証を SigV4JWT(Cognito) の2軸で整理してみました。

以前、GitHub 公式 MCP サーバを「無改変のまま」AgentCore Runtime に載せたのですが、その過程で「Runtime をどう認証して呼ぶのか」が地味に重要かつ混乱しやすいポイントだと感じたので、今回はそこを深掘りします。

TL;DR

  • AgentCore Runtime のインバウンド認証は SigV4(IAM)JWT(OAuth/OIDC) の2種類。呼ぶ主体によって使い分ける(あくまで目安。サーバ間でも JWT を使うことはあります)。
    • サーバ間(バックエンド → Runtime)は SigV4 が手軽
    • エンドユーザー(ブラウザ → Runtime)は JWT
  • JWT は CDK の RuntimeAuthorizerConfiguration.usingJWT(discoveryUrl, allowedClients) で設定する。
  • ハマった点: Cognito では 「アクセストークン」を渡す(IDトークンだと client_id mismatch で 401)。
  • ハマった点: SigV4 は Authorization ヘッダを使うので、追加トークンは別ヘッダにする(前回の X-Github-Token の話)。
  • 認証設定は CLI(get-agent-runtime)で確認できるが、マネコンには現状出てこない

前提: リージョンは ap-northeast-1、AWSアカウントは伏せ字(123456789012)で記載します。フロントは React、エージェントは Python(Strands)、IaC は AWS CDK(TypeScript) という構成です(AWS Labs の FAST テンプレートベース)。


AgentCore Runtimeの認証は2種類ある

AgentCore Runtime を InvokeAgentRuntime で呼ぶとき、Runtime 側で受け付ける認証方式は次の2つです。

SigV4 (IAM) JWT Bearer (OAuth/OIDC)
認証する相手 AWS の IAM プリンシパル IdP が発行した JWT(例: Cognito)
渡し方 リクエストを AWS資格情報でSigV4署名 Authorization: Bearer <JWT> ヘッダ
既定 デフォルト 明示的に設定が必要
向いている用途 サーバ間(バックエンド → Runtime) エンドユーザー(ブラウザ/アプリ → Runtime)
呼ぶ側の準備 IAM権限 bedrock-agentcore:InvokeAgentRuntime Runtime側にJWT authorizer設定

「どちらか一方が正解」ではなく、呼ぶ主体によって適切な方が違うのがポイントです。


実際の構成: どこでSigV4、どこでJWTか

今回のアプリでは AgentCore Runtime が2つ登場し、それぞれ認証方式が違います。

[ブラウザ(React)]
   │  ① JWT(Cognitoアクセストークン)を Authorization: Bearer で送信
   ▼
[アプリのエージェントRuntime (Strands)]
   │  ② SigV4(実行ロールのAWS資格情報で署名)
   ▼
[GitHub MCPのRuntime (以前作ったもの)]
   └─→ GitHub
  • ① ブラウザ → アプリRuntime = JWT
    ユーザーが Cognito でログインし、発行された アクセストークンAuthorization: Bearer に載せて Runtime を直接呼びます。
  • ② エージェント → MCP Runtime = SigV4
    エージェント(サーバ側)が別Runtimeを呼ぶときは、実行ロールのAWS資格情報で SigV4署名します。

なぜブラウザはSigV4を使わないのか

SigV4署名には AWSのアクセスキー/シークレットが要ります。これを公開されるブラウザに置くのは論外です。そこで、エンドユーザー向けには IdP(Cognito)のJWT を使う、というのが定石で、AgentCore Runtime もこのために JWT authorizer をサポートしています。逆にサーバ間(②)は IAMロールで完結するので SigV4 が自然、という整理です。

ただし「サーバ間=必ずSigV4」というわけでもありません。例えばエージェントが別のエージェントを呼ぶようなサーバ間通信でも、呼び出し元のユーザーIDや権限をトークンで伝えたいケースでは JWT を選ぶこともあります。ここはユースケース次第(ケースバイケース)です。SigV4 は「とりあえず IAM だけで通せる手軽さ」、JWT は「IdP に紐づくアイデンティティ/スコープを運べる」のが強み、という感覚で捉えています。


工夫①: JWT(Cognito)をCDKで設定する

AgentCore の CDK 構築子では、RuntimeAuthorizerConfiguration.usingJWT() で JWT authorizer を設定できます。

// 1. authorizer を定義
const authorizerConfiguration = agentcore.RuntimeAuthorizerConfiguration.usingJWT(
  // discoveryUrl: Cognito の OIDC ディスカバリ URL
  `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/openid-configuration`,
  // allowedClients: 許可するアプリクライアントIDの一覧
  [userPoolClientId]
)

// 2. Runtime に紐付け
new agentcore.Runtime(this, "Runtime", {
  agentRuntimeArtifact,
  // ...
  authorizerConfiguration,   // ← ここで適用
})

これは内部的に CloudFormation の AWS::BedrockAgentCore::Runtime CustomJWTAuthorizerConfiguration に展開されます。設定する中身は実質2つだけです。

プロパティ 値の例 役割
discoveryUrl https://cognito-idp.ap-northeast-1.amazonaws.com/<userPoolId>/.well-known/openid-configuration 署名検証用の公開鍵(JWKS)と発行者情報を取得し、トークンの署名・発行者を検証
allowedClients ["<appClientId>"] トークンの client_id クレームがこの一覧に含まれるかを検証

discoveryUrl は必須。allowedClients(または allowedAudience)で「誰のトークンを信頼するか」を絞ります。

JWKSJSON Web Key Set の略で、JWT の署名を検証するための公開鍵のセット(JSON)です。discoveryUrl(.well-known/openid-configuration)の中に jwks_uri が書かれており、Runtime はそこから鍵を取得してトークンの署名を検証します。鍵のローテーションにも追従できるので、Runtime 側に鍵を直接埋め込む必要がありません。


工夫②: 呼ぶ側(ブラウザ)の実装

ブラウザからは Runtime のデータプレーンに直接 fetch します。

const url =
  `https://bedrock-agentcore.${region}.amazonaws.com` +
  `/runtimes/${encodeURIComponent(runtimeArn)}/invocations?qualifier=DEFAULT`

const res = await fetch(url, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,                   // ← Cognitoアクセストークン(JWT)
    "Content-Type": "application/json",
    "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id": sessionId, // セッション識別(認証とは別)
  },
  body: JSON.stringify({ prompt, runtimeSessionId: sessionId }),
})

Runtime はトークンを検証したあと、その sub クレームをユーザーIDとして扱えます。per-user のデータ参照や認可の起点に使えて便利です。


ハマりどころ集

① 「アクセストークン」か「IDトークン」か

ここが一番ハマりました。Cognito は「IDトークン」と「アクセストークン」の2種類を発行しますが、AgentCore の JWT authorizer に渡すのはアクセストークンです。

  • IDトークンaud(audience) は持つが client_id は持たない
  • アクセストークンclient_id を持つ

ところが usingJWT(..., allowedClients)client_id を検証します。なのでIDトークンを渡すと、

401 Unauthorized (client_id mismatch)

になります。react-oidc-context を使っているなら auth.user?.access_token が正解です(id_token ではない)。

② SigV4と「Authorizationヘッダ」の競合

SigV4は署名を Authorization ヘッダに入れます。一方で下流(GitHub)に渡したいトークンも Authorization に入れたい……と競合します。

そこで以前の記事では、GitHub の PAT を X-Github-Token という別ヘッダで持ち回り、受け側(nginx)で Authorization: Bearer に詰め替える、という方式にしました。SigV4を使うときは、追加で運びたいトークンは別ヘッダにする、と覚えておくと安全です。

③ 設定がマネコンに出てこない

JWT authorizer を設定したあと、「マネコンのどこで確認できるんだろう?」と探したのですが、2026年6月現在、AgentCore のコンソール(Runtime詳細画面)に authorizer 設定は表示されませんでした。コンソールで見えるのはステータス・ARN・エンドポイント・オブザーバビリティあたりです。

「コンソールに出ない=設定されていない」ではないので、確認は次の CLI でやりましょう。

AgentCore はまだ新しいサービスなので、このあたりは今後コンソールでも見えるように対応されていく気がします(あくまで個人の予想です)。


設定の確認方法(CLIが一次情報)

設定の実体は、API/CLI で確実に確認できます(読み取りのみ)。

aws bedrock-agentcore-control get-agent-runtime \
  --agent-runtime-id <runtimeId> \
  --region ap-northeast-1

レスポンスの authorizerConfiguration.customJWTAuthorizerdiscoveryUrlallowedClients が入っていれば、JWT 認証が効いていて、どの IdP/クライアントを信頼しているかが分かります。

確認は CLI(get-agent-runtime)、正本は IaC(CDK の usingJWT(...) 定義) を見るのが確実、という整理に落ち着きました。


まとめ

  • AgentCore Runtime のインバウンド認証は SigV4(IAM)JWT(OAuth/OIDC) の2種類。呼ぶ主体で使い分ける
    • サーバ間 → SigV4 / エンドユーザー → JWT
  • JWT は CDK の usingJWT(discoveryUrl, allowedClients) で設定。実体は CustomJWTAuthorizerConfiguration
  • Cognitoではアクセストークンを渡すclient_id を検証するため。IDトークンだと401)。
  • SigV4利用時は Authorization を使うので、追加トークンは別ヘッダに(前回の X-Github-Token)。
  • 認証設定は CLI(get-agent-runtime) と IaC で確認。コンソールには現状出ない

AgentCore は「Runtime をどう呼ぶか/どう守るか」を、用途に応じて IAM と OIDC で素直に切り替えられるのが分かりやすいと感じました。同じことをやりたい方の参考になれば幸いです。


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?