

# インバウンド認証とアウトバウンド認証による認証と認可
<a name="runtime-oauth"></a>

このセクションでは、AgentCore Identity で OAuth および JWT ベアラートークンを使用して、エージェントランタイムの認証と認可を実装する方法について説明します。 [AgentCore ](identity.md) Cognito ユーザープールの設定、JWT 認証用のエージェントのランタイムの設定 (インバウンド認証）、サードパーティーリソースへの OAuth ベースのアクセスの実装 (アウトバウンド認証) を行う方法について説明します。

完全な例については、「」を参照してください[https://github.com/awslabs/amazon-bedrock-agentcore-samples/](https://github.com/awslabs/amazon-bedrock-agentcore-samples/)。

MCP サーバーで OAuth を使用する方法については、[AgentCore ランタイムで MCP サーバーをデプロイする](runtime-mcp.md)」を参照してください。

Amazon Bedrock AgentCore ランタイムは、ホストされたエージェントに 2 つの認証メカニズムを提供します。

 **IAM SigV4 認証**   
他の AWS APIs と同様に、追加の設定なしで自動的に機能するデフォルトの認証および認可メカニズム。  
 **X-Amzn-Bedrock-AgentCore-Runtime-User-Id ヘッダー**   
ソリューションでホストされたエージェントがエンドユーザーに代わって (認可コード付与を使用して) OAuth トークンを取得する必要がある場合は、リクエストに `X-Amzn-Bedrock-AgentCore-Runtime-User-Id`ヘッダーを含めることでユーザー識別子を指定できます。このヘッダーは内部的に`GetWorkloadAccessTokenForUserId`パスを使用します。  
で InvokeAgentRuntime を呼び出す`X-Amzn-Bedrock-AgentCore-Runtime-User-Id header`には、既存のアクションに加えて、新しい IAM `bedrock-agentcore:InvokeAgentRuntimeForUser` `bedrock-agentcore:InvokeAgentRuntime`アクション が必要です。
 **このヘッダーと JWT ベアラートークン認証を使用するタイミング**   
このヘッダーは、次のユースケース向けに設計されています。  
+  **カスタマーマネージドユーザー識別子を持つエンタープライズ顧客** — 独自のユーザー ID 文字列を維持し、認証情報バインディングのために AgentCore Identity に渡す必要がある組織。
+  **開発シナリオとクイックスタートシナリオ** — IdP トークンがまだ利用できず、ユーザースコープの認証情報フローをテストするための高速パスを必要とするビルダー。

  ID プロバイダーが設定されている本稼働デプロイでは、代わりに [JWT ベアラートークン認証](#oauth-sample-overview)を使用します。JWT パス (`GetWorkloadAccessTokenForJWT`) は、トークンの発行者、署名、有効期限を検証し、ユーザーの ID の暗号化証明を提供します。`X-Amzn-Bedrock-AgentCore-Runtime-User-Id` ヘッダーパスは、認証されたエンドユーザー ID に対して userId を検証しません。正しい値を渡すには呼び出し元のワークロードに依存し、提供できるユーザーを制限するには IAM ポリシーに依存します。

   **X-Amzn-Bedrock-AgentCore-Runtime-User-Id ヘッダーのセキュリティのベストプラクティス** 
**ヒント**  
すべてのランタイムセキュリティレコメンデーションの統合ビューについては、[AgentCore ランタイムのセキュリティのベストプラクティス](runtime-security-best-practices.md)」を参照してください。

  AgentCore は、ヘッダー値を認証された ID と照合せずに不透明な識別子として扱うため、セキュリティ境界を維持するために以下のコントロールを適用する必要があります。
+  **IAM アクセス許可を制限する** — 信頼されたプリンシパルのみが アクセス`bedrock-agentcore:InvokeAgentRuntimeForUser`許可を持つ必要があります。IAM リソース条件を使用して、このアクセス許可を特定のランタイムリソースにスコープします。管理ポリシーまたはワイルドカードリソースステートメントを介して広く付与しないでください。
+  **認証されたプリンシパルから user-id を取得する** — user-id 値は、クライアントが指定した任意の値を受け入れるのではなく、認証されたプリンシパルのコンテキスト (IAM 発信者 ID やユーザートークンクレームなど) から取得する必要があります。これにより、認証されたユーザーが別の を手動で指定することで、別のユーザーを偽装するのを防ぐことができます`user-id`。
+  **監査ログの実装** — 認証された IAM プリンシパル (SigV4 コンテキストから) と渡される`user-id`値との関係をログに記録します。 AWS CloudTrail を使用して、 `runtimeUserId`パラメータを含む`InvokeAgentRuntime`呼び出しをモニタリングします。
+  **信頼できないコンテキストでヘッダーを拒否する** — user-id 委任を必要としないランタイムの場合、IAM ポリシーの`bedrock-agentcore:InvokeAgentRuntimeForUser`アクションを明示的に拒否して、ヘッダーが受け入れられないようにします。

  ```
  {
     "Statement": [
        {
           "Sid": "DenyUserIdDelegation",
           "Effect": "Deny",
           "Action": "bedrock-agentcore:InvokeAgentRuntimeForUser",
           "Resource": "arn:aws:bedrock-agentcore:REGION:ACCOUNT_ID:runtime/*"
        }
     ]
  }
  ```

 **JWT ベアラートークン認証**   
エージェントの作成時にオーソライザー設定を指定することで、JWT ベアラートークンを受け入れるようにエージェントランタイムを設定できます。  
この設定には以下が含まれます。  
+ 検出 URL - OpenID Connect 検出 URLs`^.+/\.well-known/openid-configuration$`のパターンと一致する必要がある文字列
+ 許可された対象者 - JWT トークンの aud クレームに対して検証される許可された対象者のリスト
+ 許可されたクライアント - JWT トークンの client\_id クレームに対して検証される許可されたクライアント識別子のリスト
+ 許可されたスコープ - JWT トークンのスコープクレームに対して検証される許可されたスコープのリスト。`allowedScopes` 認可フィールドは文字列のリストとして設定されます。
+ 必須のカスタムクレーム - 受信 JWT トークンに含まれるクレーム名と値に対して検証される必須クレームのリスト。オーソライザーの設定の詳細については、[「インバウンド JWT オーソライザーの設定](inbound-jwt-authorizer.md)」を参照してください。

**注記**  
AgentCore ランタイムは、IAM SigV4 または JWT ベアラートークンベースのインバウンド認証のいずれかをサポートできますが、両方を同時にサポートすることはできません。AgentCore ランタイムの異なるバージョンを常に作成し、異なるインバウンド認可タイプに設定できます。Amazon Bedrock AgentCore でランタイムを作成すると、AgentCore Identity サービスでランタイムのワークロード ID が自動的に作成されます。

**Topics**
+ [ゲートウェイへの IAM (SigV4) インバウンド呼び出しを制限する](#runtime-restrict-iam-gateway)
+ [JWT インバウンド認可と OAuth アウトバウンドアクセスのサンプル](#oauth-sample-overview)
+ [前提条件](#oauth-prerequisites)
+ [ステップ 1: エージェントプロジェクトを作成する](#prepare-agent)
+ [ステップ 2: AWS Cognito ユーザープールを設定し、ユーザーを追加する](#setup-cognito)
+ [ステップ 3 (オプション): AgentCore Gateway を使用してランタイムをフロントする](#runtime-front-with-gateway)
+ [ステップ 4: エージェントをデプロイする](#deploy-agent)
+ [ステップ 5: ベアラートークンを使用してエージェントを呼び出す](#oauth-invoke-agent)
+ [OAuth エラーレスポンス](#oauth-error-responses)
+ [ステップ 6: OAuth を使用してツールにアクセスするようにエージェントを設定する](#oauth-outbound-access)
+ [ステップ 7: (オプション) JWT トークンを AgentCore ランタイムに伝播する](#oauth-propagate-jwt-token)
+ [トラブルシューティング](#troubleshooting)

## ゲートウェイへの IAM (SigV4) インバウンド呼び出しを制限する
<a name="runtime-restrict-iam-gateway"></a>

AgentCore ランタイムを AgentCore Gateway でフロントして、ゲートウェイがランタイムへの単一の管理エントリポイントになるようにできます。これにより、ポリシーベースの認可、Amazon Bedrock ガードレール、リクエストとレスポンスのインターセプター、統合オブザーバビリティが提供され、すべてエージェント独自の環境外で適用されます。詳細な理論的根拠と設定方法については、[「Front your runtime with an AgentCore Gateway](runtime-security-best-practices.md#security-bp-front-with-gateway)」を参照してください。

ただし、これは、発信者がゲートウェイを直接バイパスしてランタイムに到達できない場合にのみ役立ちます。ランタイムがデフォルトの IAM (SigV4) インバウンド認可を使用している場合、ゲートウェイへの呼び出しを制限して、トラフィックがランタイムに到達するようにすることができます。これを実現するには、ゲートウェイの実行ロールへの呼び出しを制限するリソースベースのポリシーをランタイムにアタッチします。ゲートウェイはサービスロールを引き受けてランタイムへのリクエストに署名するため、ゲートウェイロールはランタイムを呼び出すプリンシパルです。そのロールを許可し、他のすべてのプリンシパル`Deny`に明示的な を追加して、許可されたアイデンティティベースのポリシーでも他のアイデンティティがランタイムを呼び出せないようにします。ランタイムのリソースベースのポリシーの詳細については、[「Amazon Bedrock AgentCore のリソースベースのポリシー](resource-based-policies.md)」を参照してください。

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowOnlyGatewayRole",
            "Effect": "Allow",
            "Principal": { "AWS": "arn:aws:iam::111122223333:role/MyGatewayExecutionRole" },
            "Action": "bedrock-agentcore:InvokeAgentRuntime",
            "Resource": "arn:aws:bedrock-agentcore:us-west-2:111122223333:runtime/RUNTIME_ID"
        },
        {
            "Sid": "DenyOtherPrincipals",
            "Effect": "Deny",
            "Principal": { "AWS": "*" },
            "Action": "bedrock-agentcore:InvokeAgentRuntime",
            "Resource": "arn:aws:bedrock-agentcore:us-west-2:111122223333:runtime/RUNTIME_ID",
            "Condition": {
                "ArnNotEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::111122223333:role/MyGatewayExecutionRole"
                }
            }
        }
    ]
}
```

**ヒント**  
明示的な は`Allow`、同じアカウントのアイデンティティベースのポリシーを含むすべての `Deny`を常に上書きします。`Deny` を にキー設定すると`aws:PrincipalArn`、アカウントに存在する他のアクセス許可に関係なく、ゲートウェイの実行ロールのみがランタイムを呼び出すことができます。

**重要**  
ランタイムをゲートウェイの実行ロールに制限することは、そのロールを引き受けることができるユーザーに対するコントロールと同じくらい強力です。ゲートウェイ実行ロールを引き受けることができるプリンシパルは、ゲートウェイであるかのようにランタイムを呼び出すことができます。**ゲートウェイ実行ロールの**信頼ポリシーに `aws:SourceArn`および `aws:SourceAccount`条件を追加してロールをロックし、ゲートウェイのみがロールを引き受けられるようにします。[混乱した代理防止](runtime-security-best-practices.md#security-bp-confused-deputy)ガイダンスは、ランタイムの実行ロールに適用されるのと同じ手法を示しています。ここでは同じパターンを適用しますが、ゲートウェイ実行ロールとスコープの信頼ポリシー`aws:SourceArn`をゲートウェイ ARN に設定します。

## JWT インバウンド認可と OAuth アウトバウンドアクセスのサンプル
<a name="oauth-sample-overview"></a>

このガイドでは、JWT 形式を使用して OAuth 準拠のアクセストークンで呼び出されるようにエージェントランタイムを設定するプロセスについて説明します。サンプルエージェントは、 AWS Cognito アクセストークンを使用して承認されます。後で、エージェントコードがユーザーに代わって Google トークンを取得し、Google Drive をチェックしてコンテンツを取得する方法についても説明します。

 **学習内容** 

このガイドでは、以下の方法について説明します。
+ Cognito ユーザープールの設定、ユーザーの追加、ユーザーのベアラートークンの取得
+ 認可に Cognito ユーザープールを使用するようにエージェントのランタイムを設定する
+ ユーザーに代わって OAuth トークンを取得してツールを呼び出すようにエージェントコードを設定する

## 前提条件
<a name="oauth-prerequisites"></a>

開始する前に、以下の準備が整っていることを確認します。
+ 適切なアクセス許可を持つ AWS アカウント
+ Python プログラミングの基本的な理解
+ Docker コンテナに関する知識 (高度なデプロイ用)
+ ランタイムで基本エージェントを正常にセットアップする
+ 最新の CLI AWS と `jq`がインストールされている
+ OAuth 認可、主に JWT ベアラートークン、クレーム、およびさまざまなグラントフローに関する基本的な理解

## ステップ 1: エージェントプロジェクトを作成する
<a name="prepare-agent"></a>

`agentcore create` コマンドを使用して、選択したフレームワークでスケルトンエージェントプロジェクトを設定します。

```
agentcore create
```

コマンドは、次のプロンプトを表示します。
+ フレームワークを選択する (このチュートリアルでは Strands エージェントを選択する)
+ プロジェクト名を指定する
+ 追加オプションを設定する

これにより、以下が生成されます。
+ 選択したフレームワークを持つエージェントコード
+  `agentcore/agentcore.json` 設定ファイル
+  `requirements.txt` 必要な依存関係を持つ

**注記**  
生成されたエージェントコードは、次のステップで OAuth 認証を実装するための基盤として機能します。

## ステップ 2: AWS Cognito ユーザープールを設定し、ユーザーを追加する
<a name="setup-cognito"></a>

Cognito ユーザープールをセットアップしてユーザーを作成するには、プロセスを自動化するシェルスクリプトを使用します。

詳細については、[「ステップ 2: ID と認証モジュールをインポートする](identity-getting-started-google.md#identity-getting-started-step2)」を参照してください。

<a name="setup-cognito"></a> **Cognito ユーザープールをセットアップしてユーザーを作成するには** 
+ 以下の内容で `setup_cognito.sh` という名前のファイルを作成します。

  ```
  #!/bin/bash
  
  # Create User Pool and capture Pool ID directly
  export POOL_ID=$(aws cognito-idp create-user-pool \
    --pool-name "MyUserPool" \
    --policies '{"PasswordPolicy":{"MinimumLength":8}}' \
    --region $REGION | jq -r '.UserPool.Id')
  
  # Create App Client and capture Client ID directly
  export CLIENT_ID=$(aws cognito-idp create-user-pool-client \
    --user-pool-id $POOL_ID \
    --client-name "MyClient" \
    --no-generate-secret \
    --explicit-auth-flows "ALLOW_USER_PASSWORD_AUTH" "ALLOW_REFRESH_TOKEN_AUTH" \
    --region $REGION | jq -r '.UserPoolClient.ClientId')
  
  # Create User
  aws cognito-idp admin-create-user \
    --user-pool-id $POOL_ID \
    --username $USERNAME \
    --region $REGION \
    --message-action SUPPRESS > /dev/null
  
  # Set Permanent Password
  aws cognito-idp admin-set-user-password \
    --user-pool-id $POOL_ID \
    --username $USERNAME \
    --password $PASSWORD \
    --region $REGION \
    --permanent > /dev/null
  
  # Authenticate User and capture Access Token
  export BEARER_TOKEN=$(aws cognito-idp initiate-auth \
    --client-id "$CLIENT_ID" \
    --auth-flow USER_PASSWORD_AUTH \
    --auth-parameters USERNAME=$USERNAME,PASSWORD=$PASSWORD \
    --region $REGION | jq -r '.AuthenticationResult.AccessToken')
  
  # Output the required values
  echo "Pool id: $POOL_ID"
  echo "Discovery URL: https://cognito-idp.$REGION.amazonaws.com/$POOL_ID/.well-known/openid-configuration"
  echo "Client ID: $CLIENT_ID"
  echo "Bearer Token: $BEARER_TOKEN"
  ```

  ターミナルウィンドウを開き、次の環境変数を設定します。
  +  {{REGION}} – 使用する AWS リージョン
  +  {{USERNAME}} – 新しいユーザーのユーザー名
  +  {{PASSWORD}} – 新しいユーザーのパスワード

    ```
    export REGION=us-east-1 // set your desired Region
    export USERNAME=USER NAME
    export PASSWORD=PASSWORD
    ```

    ターミナルウィンドウで、スクリプトを実行します。

    ```
    source setup_cognito.sh
    ```

    スクリプトからの出力を書き留めます。これらの値は次のステップで必要になります。

このスクリプトは、Cognito ユーザープール、ユーザープールクライアントを作成し、ユーザーを追加し、ユーザーのベアラートークンを生成します。トークンはデフォルトで 60 分間有効です。

## ステップ 3 (オプション): AgentCore Gateway を使用してランタイムをフロントする
<a name="runtime-front-with-gateway"></a>

AgentCore ランタイムを AgentCore Gateway でフロントして、ゲートウェイがランタイムへの単一の管理エントリポイントになるようにできます。これにより、ポリシーベースの認可、Amazon Bedrock ガードレール、リクエストとレスポンスのインターセプター、統合オブザーバビリティが提供され、すべてエージェント独自の環境外で適用されます。詳細な理論的根拠と設定方法については、[「Front your runtime with an AgentCore Gateway](runtime-security-best-practices.md#security-bp-front-with-gateway)」を参照してください。

このランタイムをフロントする場合は、次のステップでランタイムをデプロイする前に、今すぐ[ゲートウェイを作成します](gateway-create.md)。デプロイ後、[ランタイムをゲートウェイターゲットとして追加](gateway-target-http-runtime.md)します。

発信者がゲートウェイをバイパスできないようにするには、そのゲートウェイからの呼び出しのみを受け入れるようにランタイムを制限します。これは次のステップで、オーソライザーの一部として を使用して設定します `allowedWorkloadConfiguration` ([「 allowedWorkloadConfiguration: restrict invocation to your gateway](#deploy-agent-allowed-workload)」を参照）。

## ステップ 4: エージェントをデプロイする
<a name="deploy-agent"></a>

**重要**  
**2025 年 10 月 13** 日以降、Amazon Bedrock AgentCore は、新しいエージェントに手動 IAM ポリシー設定を必要とせずに、ワークロード ID アクセス許可にサービスにリンクされたロール (SLR) を使用します。  
サービスにリンクされたロールの詳細:  
 **名前**: `AWSServiceRoleForBedrockAgentCoreRuntimeIdentity` 
 **サービスプリンシパル:** `runtime-identity.bedrock-agentcore.amazonaws.com` 
 **目的:** ワークロード ID アクセストークンと OAuth 認証情報を管理する
AgentCore Control APIs呼び出しに使用するロールに、サービスにリンクされたロールを作成するアクセス許可があることを確認します。  

```
{
    "Sid": "CreateBedrockAgentCoreIdentityServiceLinkedRolePermissions",
    "Effect": "Allow",
    "Action": "iam:CreateServiceLinkedRole",
    "Resource": "arn:aws:iam::*:role/aws-service-role/runtime-identity.bedrock-agentcore.amazonaws.com/AWSServiceRoleForBedrockAgentCoreRuntimeIdentity",
    "Condition": {
        "StringEquals": {
            "iam:AWSServiceName": "runtime-identity.bedrock-agentcore.amazonaws.com"
        }
    }
}
```
 **メリット**: サービスにリンクされたロールは、手動ポリシー設定を必要とせずに、ワークロード ID アクセスに必要なアクセス許可を自動的に提供します。  
サービスにリンクされたロールの詳細については、[「 Identity service-linked role](service-linked-roles.md#identity-service-linked-role)」を参照してください。

次に、作成した Cognito ユーザープールを使用して JWT 認可でエージェントをデプロイします。オーソライザー設定でエージェントを作成する必要があります。次の表は、さまざまなオーソライザー設定パラメータと、それらを使用して受信トークンを検証する方法を示しています。


| authorizer\_configuration | デコードされたトークンの クレーム | 注意事項 | 
| --- | --- | --- | 
| 検出 URL → 発行者 | iss | 検出 URL は発行者 URL を指す必要があります。これは、デコードされたトークンの iss クレームと一致する必要があります。 | 
| allowedClients | client\_id | トークンの client\_id は、オーソライザーで指定された許可されたクライアントのいずれかと一致する必要があります | 
| allowedAudience | aud | トークンからの aud クレームの値の 1 つは、オーソライザーで指定された許可された対象者の 1 つと一致する必要があります | 
| allowedWorkloadConfiguration |  `internal`  | オプション。起動時に、AgentCore Gateway のみがランタイムを呼び出すことを許可するために使用されます。[「ゲートウェイへの呼び出しを制限する](#deploy-agent-allowed-workload)」を参照してください。 | 

client\_id と aud の両方が指定されている場合、エージェントランタイムオーソライザーは両方を検証します。

### allowedWorkloadConfiguration: ゲートウェイへの呼び出しを制限する
<a name="deploy-agent-allowed-workload"></a>

の `allowedWorkloadConfiguration`フィールドは、リクエストの ID チェーン内のどのワークロードがランタイムを呼び出すことができるか`customJWTAuthorizer`を制限します。許可されたワークロードをゲートウェイに設定して、アイデンティティチェーンにそのゲートウェイが含まれている場合にのみランタイムがリクエストを受け入れるようにします。これにより、OAuth (JWT) ランタイムは、ステップ 3 で設定したゲートウェイを介してのみトラフィックが到着するように強制します。

許可されたワークロードは、次のいずれかのフィールドを使用して指定します。一方または両方を指定できます。アイデンティティチェーンが**いずれかの**フィールドのエントリと一致する場合、リクエストが受け入れられるため、両方を提供する必要はありません。
+  **hostingEnvironments** – ワークロードがターゲットを呼び出すことが許可されているホスティング環境のリスト。各エントリは、 を持つオブジェクトです`arn`。起動時にサポートされているホスティング環境は AgentCore Gateway のみであるため、それぞれが AgentCore Gateway ARN `arn`である必要があります。
+  **workloadIdentities** – ターゲットの呼び出しが許可されているワークロードアイデンティティ名のリスト。ワークロード ID 名は ARN **ではありません**。これはゲートウェイのワークロードアイデンティティ ARN の最後のセグメントであり、`GetGateway`レスポンスの `workloadIdentityDetails`フィールドにあります。たとえば、 `workloadIdentityDetails.workloadIdentityArn`が の場合`arn:aws:bedrock-agentcore:us-east-1:111122223333:workload-identity-directory/default/workload-identity/my-gateway-workload-identity`、ワークロード ID 名は です`my-gateway-workload-identity`。

次の例では、ARN によって特定の AgentCore Gateway への呼び出しを制限するエージェントランタイムを作成します。ゲートウェイを許可する最も簡単な方法は、 を`hostingEnvironments`単独で指定することです。

```
{
    "authorizerConfiguration": {
        "customJWTAuthorizer": {
            "discoveryUrl": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_example/.well-known/openid-configuration",
            "allowedClients": ["your-client-id"],
            "allowedWorkloadConfiguration": {
                "hostingEnvironments": [
                    {
                        "arn": "arn:aws:bedrock-agentcore:us-east-1:111122223333:gateway/my-gateway-id"
                    }
                ]
            }
        }
    }
}
```

または、ワークロード ID 名でゲートウェイを識別するか、両方のフィールドを指定することもできます。両方が存在する場合、いずれかのフィールドのエントリと一致するリクエストが許可されます。次のスニペットでは、ARN で識別されるゲートウェイとワークロード ID 名で識別されるゲートウェイの `allowedWorkloadConfiguration` 2 つの異なるゲートウェイを使用できます。

```
"allowedWorkloadConfiguration": {
    "hostingEnvironments": [
        {
            "arn": "arn:aws:bedrock-agentcore:us-east-1:111122223333:gateway/my-gateway-1-id"
        }
    ],
    "workloadIdentities": [
        "my-gateway-2-workload-identity"
    ]
}
```

**注記**  
起動時に、 `allowedWorkloadConfiguration`は AgentCore ランタイムターゲットでのみサポートされ、許可されるワークロードは AgentCore Gateway です。

### エージェントランタイムを作成してデプロイする
<a name="deploy-agent-create-deploy"></a>

オーソライザー設定の準備ができたら、エージェントランタイムを作成してデプロイします。次の例は、AgentCore CLI または AWS SDK for Python (Boto3) を使用してこれを行う方法を示しています。出力のエージェントランタイム ARN を書き留めます。次のステップでエージェントを呼び出すために必要になります。

**Example**  
 **エージェントを設定してデプロイするには**   

1. AgentCore CLI を使用してエージェントプロジェクトを作成します。

   ```
   agentcore create
   ```

   プロンプトが表示されたら、フレームワークを選択します (このチュートリアルではストランドエージェントを選択します）。

1. エージェントをデプロイします。

   ```
   agentcore deploy
   ```

1. 出力のエージェントランタイム ARN を書き留めます。これは次のステップで必要になります。
**ヒント**  
フラグなしで `agentcore create` コマンドを実行して、プロジェクトのセットアップをガイドする完全にインタラクティブなエクスペリエンスを実現することもできます。

1. 

   ```
   import boto3
   
   # Create the client
   client = boto3.client('bedrock-agentcore-control', region_name="us-east-1")
   
   # Call the CreateAgentRuntime operation
   response = client.create_agent_runtime(
       agentRuntimeName='HelloAgent',
       agentRuntimeArtifact={
           'containerConfiguration': {
               'containerUri': '111122223333.dkr.ecr.us-east-1.amazonaws.com/my-agent:latest'
           }
       },
       authorizerConfiguration={
           "customJWTAuthorizer": {
               "discoveryUrl": 'COGNITO_DISCOVERY_URL',
               "allowedClients": ['COGNITO_CLIENT_ID']
           }
       },
       networkConfiguration={"networkMode":"PUBLIC"},
       roleArn='arn:aws:iam::111122223333:role/AgentRuntimeRole',
       lifecycleConfiguration={
           'idleRuntimeSessionTimeout': 300,  # 5 min, configurable
           'maxLifetime': 1800                # 30 minutes, configurable
       },
   )
   ```

## ステップ 5: ベアラートークンを使用してエージェントを呼び出す
<a name="oauth-invoke-agent"></a>

エージェントが JWT 認可でデプロイされたので、ベアラートークンを使用してエージェントを呼び出すことができます。

**注記**  
[ステップ 3](#runtime-front-with-gateway) でランタイムにゲートウェイを前面配置した場合は、 を呼び出す前にデプロイされたランタイムをゲートウェイターゲットとして追加します。[AgentCore ランタイムターゲット](gateway-target-http-runtime.md)」を参照し、ランタイムエンドポイントではなく、次の例に示すゲートウェイエンドポイントを介して を呼び出します。

**重要**  
 **既存のユーザーにとって重要**: **2025 年 10 月 13 日より前に作成されたエージェントは、**引き続き ID アクセス許可にエージェント実行ロールを使用し、前述のポリシーをエージェントの実行ロールにアタッチ**する必要があります**。  
 **新しいエージェント** : **2025 年 10 月 13 日以降に**作成されたエージェントの場合、アクセス許可はサービスにリンクされたロールによって自動的に処理されるため、このポリシー**は必要ありません**。  

```
{
    "Sid": "GetAgentAccessToken",
    "Effect": "Allow",
    "Action": [
        "bedrock-agentcore:GetWorkloadAccessToken",
        "bedrock-agentcore:GetWorkloadAccessTokenForJWT",
        "bedrock-agentcore:GetWorkloadAccessTokenForUserId"
    ],
    # point to the workload identity for the runtime; the workload identity can be found in
    # the GetAgentRuntime response and has your agent name in it.
    "Resource": [
        "arn:aws:bedrock-agentcore:region:account-id:workload-identity-directory/default",
        "arn:aws:bedrock-agentcore:region:account-id:workload-identity-directory/default/workload-identity/agentname-*"
    ]
}
```

 **エージェントを呼び出す** 

Amazon Cognito で作成したユーザーのベアラートークンを取得します。

```
# use the password and other details used when you created the cognito user

export TOKEN=$(aws cognito-idp initiate-auth \
    --client-id "$CLIENT_ID" \
    --auth-flow USER_PASSWORD_AUTH \
    --auth-parameters USERNAME='testuser',PASSWORD='PASSWORD' \
    --region us-east-1 | jq -r '.AuthenticationResult.AccessToken')
```

残りの手順でエージェントを呼び出します。

OAuth でエージェントを呼び出します。

**Example**  

1. 

   ```
   // Invoke with OAuth token
   export PAYLOAD='{"prompt": "hello what is 1+1?"}'
   
   export BEDROCK_AGENT_CORE_ENDPOINT_URL="https://bedrock-agentcore.us-east-1.amazonaws.com"
   # If you fronted the runtime with a gateway (Step 3), the core endpoint URL is now your gateway URL
   # export BEDROCK_AGENT_CORE_ENDPOINT_URL="https://${GATEWAY_ID}.gateway.bedrock-agentcore.us-east-1.amazonaws.com/${TARGET_NAME}"
   
   export INVOKE_URL="${BEDROCK_AGENT_CORE_ENDPOINT_URL}/runtimes/${ESCAPED_AGENT_ARN}/invocations?qualifier=DEFAULT"
   # If you fronted the runtime with a gateway (Step 3), the preceding URL works but there is also a simpler alternative:
   # export INVOKE_URL="${BEDROCK_AGENT_CORE_ENDPOINT_URL}/invocations"
   
   curl -v -X POST "${INVOKE_URL}" \
   -H "Authorization: Bearer ${TOKEN}" \
   -H "X-Amzn-Trace-Id: your-trace-id" \
   -H "Content-Type: application/json" \
   -H "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id: your-session-id" \
   -d ${PAYLOAD}
   ```

1. boto3 はベアラートークンを使用した呼び出しをサポートしていないため、Python のリクエストライブラリなどの HTTP クライアントを使用する必要があります。

   <a name="invoke-agent"></a> **ベアラートークンを使用してエージェントを呼び出すには** 

1. 次の内容`invoke_agent.py`で という名前の Python スクリプトを作成します。

   ```
   import requests
   import urllib.parse
   import json
   import os
   
   # Configuration Constants
   REGION_NAME = "AWS_REGION"
   
   # === Agent Invocation Demo ===
   invoke_agent_arn = "YOUR_AGENT_ARN_HERE"
   auth_token = os.environ.get('TOKEN')
   print(f"Using Agent ARN from environment: {invoke_agent_arn}")
   
   # URL encode the agent ARN
   escaped_agent_arn = urllib.parse.quote(invoke_agent_arn, safe='')
   
   # Construct the URL — invoke the runtime directly
   url = f"https://bedrock-agentcore.{REGION_NAME}.amazonaws.com/runtimes/{escaped_agent_arn}/invocations?qualifier=DEFAULT"
   
   # If you are fronting the runtime with a gateway (see Step 3), invoke through
   # the gateway target instead (replace GATEWAY_ID and my-target):
   # url = f"https://GATEWAY_ID.gateway.bedrock-agentcore.{REGION_NAME}.amazonaws.com/my-target/invocations"
   
   # Set up headers
   headers = {
       "Authorization": f"Bearer {auth_token}",
       "X-Amzn-Trace-Id": "your-trace-id",
       "Content-Type": "application/json",
       "X-Amzn-Bedrock-AgentCore-Runtime-Session-Id": "testsession123"
   }
   
   # Enable verbose logging for requests
   import logging
   logging.basicConfig(level=logging.DEBUG)
   logging.getLogger("urllib3.connectionpool").setLevel(logging.DEBUG)
   
   invoke_response = requests.post(
       url,
       headers=headers,
       data=json.dumps({"prompt": "Hello what is 1+1?"})
   )
   
   # Print response in a safe manner
   print(f"Status Code: {invoke_response.status_code}")
   print(f"Response Headers: {dict(invoke_response.headers)}")
   
   # Handle response based on status code
   if invoke_response.status_code == 200:
       response_data = invoke_response.json()
       print("Response JSON:")
       print(json.dumps(response_data, indent=2))
   elif invoke_response.status_code >= 400:
       print(f"Error Response ({invoke_response.status_code}):")
       error_data = invoke_response.json()
       print(json.dumps(error_data, indent=2))
   
   else:
       print(f"Unexpected status code: {invoke_response.status_code}")
       print("Response text:")
       print(invoke_response.text[:500])
   ```

1. {{AWS\_REGION}} を、ステップ 3 で使用している AWS リージョンに置き換えます。

1. {{YOUR\_AGENT\_ARN\_HERE}} をステップ 3 の実際のエージェントランタイム ARN に置き換えます。

1.  スクリプトを実行します。

   ```
   python invoke_agent.py
   ```

## OAuth エラーレスポンス
<a name="oauth-error-responses"></a>

OAuth 設定のエージェントは、[RFC 6749 (OAuth 2.0) ](https://datatracker.ietf.org/doc/html/rfc6749)認証標準に従います。認証がない場合、サービスは WWW-Authenticate ヘッダー ([RFC 7235](https://datatracker.ietf.org/doc/html/rfc7235) ごと) を含む 401 Unauthorized レスポンスを返します。これにより、クライアントは GetRuntimeProtectedResourceMetadata API を通じて認可サーバーエンドポイントを検出できます。

### 401 未承認 - 認証がありません
<a name="oauth-401-missing-authentication"></a>

認可ヘッダーにベアラートークンが指定されていない場合、レスポンスは次のようになります。

```
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://bedrock-agentcore.{region}.amazonaws.com/runtimes/{ESCAPED_ARN}/invocations/.well-known/oauth-protected-resource?qualifier={QUALIFIER}"
```

WWW-Authenticate ヘッダーの `resource_metadata` URL は、保護されたリソースメタデータ (PRM) API を指します。PRM API を使用すると、クライアントはこのエージェントとその OAuth エンドポイント URLs。

**注記**  
検出されたエンドポイントを使用する`client_id`前に ( AWS コンソールまたは CLI を介して) Cognito で OAuth クライアントを事前登録して、 を取得する必要があります。Amazon Cognito は動的クライアント登録 (RFC 7591) をサポートしていません。

## ステップ 6: OAuth を使用してツールにアクセスするようにエージェントを設定する
<a name="oauth-outbound-access"></a>

このセクションでは、エージェントコードを AgentCore 認証情報プロバイダーに接続して、OAuth2 認証を使用して外部リソースに安全にアクセスする方法について説明します。

次の例は、エージェントランタイムで実行されているエージェントがユーザーに OAuth 同意をリクエストし、Google アカウントで認証し、エージェントが Google ドライブコンテンツにアクセスすることを許可する方法を示しています。

ID の設定の詳細については、[AgentCore Identity の開始方法](identity-getting-started.md)」を参照してください。

### ステップ 6.1: 認証情報プロバイダーを設定する
<a name="setup-credential-providers"></a>

Google 認証情報プロバイダーを設定するには、以下を行う必要があります。

1. アプリケーションを Google に登録してクライアント ID とクライアントシークレットを取得する

1. CLI を使用して OAuth AWS 認証情報プロバイダーを作成します。{{your-client-id}} と {{your-client-secret}} を実際の Google OAuth2 クライアント ID とクライアントシークレットに置き換えます。

   ```
   OAUTH2_CREDENTIAL_PROVIDER_RESPONSE=$(aws bedrock-agentcore-control create-oauth2-credential-provider \
     --name "google-provider" \
     --credential-provider-vendor "GoogleOauth2" \
     --oauth2-provider-config-input '{
         "googleOauth2ProviderConfig": {
           "clientId": "your-client-id",
           "clientSecret": "your-client-secret"
         }
       }' \
   --output json)
   
   OAUTH2_CALLBACK_URL=$(echo $OAUTH2_CREDENTIAL_PROVIDER_RESPONSE | jq -r '.callbackUrl')
   
   echo "OAuth2 Callback URL: $OAUTH2_CALLBACK_URL"
   ```
**注記**  
[CreateOauth2CredentialProvider](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateOauth2CredentialProvider.html) レスポンス`callbackUrl`から を取得し、Google アプリケーションのリダイレクト URI リストに URI を追加します。コールバック URL は次のようになります。https://bedrock-agentcore.us-east-1.amazonaws.com/identities/oauth2/callback/\*\*\*\*\*\*\*\*-\*\*\*\*-\*\*\*\*-\*\*\*\*\*\*\*\*\*\*\*\*

呼び出しロールに、認証情報プロバイダーにアクセスするために必要なアクセス許可があることを確認します。

### ステップ 6.2: エージェントが Google Drive の内容を読み取れるようにする
<a name="enable-google-drive-access"></a>

次の例に示すように、エージェントコア SDK 注釈を使用してツールを作成し、3 レッグの OAuth プロセスを自動的に開始します。エージェントがこのツールを呼び出すと、ユーザーはブラウザで認可 URL を開き、エージェントが Google Drive にアクセスするための同意を付与するように求められます。

```
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token, requires_api_key

# This annotation helps agent developer to obtain access tokens from external applications
@requires_access_token(
    provider_name="google-provider",
    scopes=["https://www.googleapis.com/auth/drive.metadata.readonly"], # Google OAuth2 scopes
    auth_flow="USER_FEDERATION", # 3LO flow
    on_auth_url=lambda x: print("Copy and paste this authorization url to your browser: ", x), # prints authorization URL to console
    force_authentication=True,
    callback_url='insert_oauth2_callback_url_for_session_binding'
)
async def read_from_google_drive(*, access_token: str):
    print(access_token) #You can see the access_token
    # Make API calls...
    main(access_token)

asyncio.run(read_from_google_drive(access_token=""))
```

**注記**  
[セッションバインディング](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html)を処理するローカルコールバックサーバーの実装例については、「」を参照してください。 [https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py](https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py)

 **舞台裏で何が起こるか** 

このコードを実行すると、次のプロセスが発生します。

1. エージェントランタイムは、設定されたオーソライザーに従ってインバウンドトークンを承認します。

1. エージェントランタイムは、このトークンを `bedrock-agentcore:GetWorkloadAccessTokenForJWT` API 経由でワークロードアクセストークンと交換し、ペイロードヘッダー を介してエージェントコードに配信します`WorkloadAccessToken`。

1. ツールの呼び出し中、エージェントはこのワークロードアクセストークンを使用して Token Vault API を呼び出し`bedrock-agentcore:GetResourceOauth2Token`、3LO 認証 URL を生成します。

1. エージェントは、 `on_auth_url`メソッドで指定されたとおりに、この URL をクライアントアプリケーションに送信します。

1. クライアントアプリケーションはこの URL をユーザーに提示し、ユーザーはエージェントが Google ドライブにアクセスするための同意を付与します。

1. AgentCore Identity サービスは、有効期限が切れるまで Google アクセストークンを安全に受信してキャッシュするため、ユーザーがすべてのリクエストに同意しなくても、ユーザーからの後続のリクエストでこのトークンを使用できます。

**注記**  
AgentCore Identity Service は、エージェントのワークロードアイデンティティとユーザー ID ( AWS Cognito トークンなどのインバウンド JWT トークンから) をバインディングキーとして使用して Google アクセストークンを AgentCore トークンボールトに保存し、Google トークンの有効期限が切れるまで繰り返される同意リクエストを排除します。

## ステップ 7: (オプション) JWT トークンを AgentCore ランタイムに伝播する
<a name="oauth-propagate-jwt-token"></a>

必要に応じて、認可ヘッダーを AgentCore ランタイムに渡し、クレームを抽出できます。これは、リクエストヘッダーの許可リスト設定を使用して行うことができます。詳細については、「[RequestHeaderConfiguration](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_RequestHeaderConfiguration.html)」を参照してください。

### ステップ 7.1: ヘッダーを読み取るようにエージェントコードを変更する
<a name="oauth-propagate-jwt-token-modify-code"></a>

このステップでは、PyJWT ライブラリを使用して JWT トークンからクレームをデコードおよび抽出できるように、エージェントコードを変更します。

 **requirements.txt** 

生成されたプロジェクトの `requirements.txt` ファイルに PyJWT 依存関係を追加します。

```
PyJWT
```

 **エージェントコードを更新する** 

次のコードに示すように、生成されたプロジェクトのメインエージェントファイル (フレームワークの選択に応じて、通常は `src/main.py`または類似) を変更します。ここでトークン署名の検証をスキップできます。これは、インバウンド認可が完了したときに AgentCore ランタイムによって既に検証されているためです。

```
import jwt
import json
....

@app.entrypoint
def invoke(payload, context):
    auth_header = context.request_headers.get('Authorization')
    if not auth_header:
        return None

    # Remove "Bearer " prefix if present
    token = auth_header.replace('Bearer ', '') if auth_header.startswith('Bearer ') else auth_header
    try:
        # Skip signature validation as agent runtime has validated the token already.
        claims = jwt.decode(token, options={"verify_signature": False})
        app.logger.info("Claims: %s", json.dumps(claims))
    except jwt.InvalidTokenError as e:
        app.logger.exception("Invalid JWT token: %s", e)

    .....
```

### ステップ 7.2: リクエストヘッダー許可リストを使用してエージェントを作成する
<a name="oauth-propagate-jwt-token-create-agent"></a>

AgentCore CLI を使用して、リクエストヘッダー許可リストでエージェントを設定します。生成されたプロジェクトディレクトリに移動し、以下を実行します。

```
agentcore create --name HelloAgent --framework Strands --model-provider Bedrock --memory none

# Now deploy the agent runtime
agentcore deploy
```

**注記**  
AgentCore CLI は、プロジェクト構造と設定ファイルを作成します。フレームワークの選択`agentcore/agentcore.json`に応じて、 でエージェント設定を調整します。

### ステップ 7.3: エージェントを呼び出す
<a name="oauth-propagate-jwt-token-invoke-agent"></a>

 OAuth [を使用してエージェントを呼び出す](#oauth-invoke-agent)と、CloudWatch Logs のエージェントログにクレームが表示されます。

## トラブルシューティング
<a name="troubleshooting"></a>

### トークン関連の問題をデバッグする方法
<a name="debug-token-issues"></a>

トークン認証で問題が発生した場合は、トークンをデコードしてその内容を検査できます。

```
echo "$TOKEN" | cut -d '.' -f2 | tr '_-' '/+' | awk '{ l=4 - length($0)%4; if (l<4) printf "%s", $0; for (i=0; i<l; i++) printf "="; print "" }' | base64 -D | jq
```

これにより、トークンのペイロードが出力され、次のようになります。

```
{
    "sub": "subid",
    "iss": "https://cognito-idp.us-east-1.amazonaws.com/userpoolid",
    "client_id": "clientid",
    "origin_jti": "originjti",
    "event_id": "eventid",
    "token_use": "access",
    "scope": "aws.cognito.signin.user.admin",
    "auth_time": 1752275688,
    "exp": 1752279288,
    "iat": 1752275688,
    "jti": "jti",
    "username": "username"
}
```

トークンの問題をトラブルシューティングする場合は、以下を確認してください。
+ エージェントオーソライザーの検出 URL が指す発行者 URL は、トークンの発行者クレームと一致する必要があります。以下を実行して、一致することを確認します。
  + エージェントの作成時にオーソライザー設定で指定した検出 URL を選択します。次に例を示します。 `https://cognito-idp.us-east-1.amazonaws.com/us-east-1_nnnnnnnnn/.well-known/openid-configuration`
    + 発行者の URL を確認する - `"issuer": "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_12345566"` 。これは、トークンの iss クレーム値と一致する必要があります。
+  `client_id` トークンの クレームは、指定されている場合、オーソライザー allowedClients エントリのいずれかと一致する必要があります
  + エージェントの作成時に指定したクライアント ID を書き留めます。
  + これがデコードされたトークンの client\_id クレームと一致することを確認します。
+  `aud` トークンの クレームは、指定されている場合、オーソライザー`allowedAudience`エントリのいずれかと一致する必要があります
  + エージェントの作成時に指定したオーディエンスリストを書き留めます。
  + これがデコードされたトークンの`aud`クレームと一致することを確認します。
+ トークンは数分のみ有効です (デフォルトの Amazon Cognito の有効期限は 60 分です）。必要に応じて新しいトークンを取得します。