概要
トークン交換を使用すると、クライアントは既存のアクセストークンを、異なるサービスをスコープとする新しいアクセストークンに交換できます。例えば、旅行計画エージェントは、従業員を再度ログインさせることなく、従業員のトークンを人事 (HR) MCP サービスへの読み取り専用アクセスを許可するトークンに交換できます。
この機能は RFC 8693 (OAuth 2.0 Token Exchange) を実装しており、Agent Identity Security が有効になっているすべての IDaaS インスタンスで利用できます。
プロトコルの背景情報とサポートされているグラントフローについては、「トークン交換とは」をご参照ください。
事前準備
トークン交換は、エージェントアプリケーションではデフォルトで有効になっています。追加の設定は不要です。
制限事項
項目 | 制約 |
トークン発行者 | 同じ IDaaS 認可サーバーによって発行されたトークンのみ交換できます。 |
クライアントの権限付与 | 呼び出し元のクライアントは、ターゲットのオーディエンスとスコープに対してすでに権限が付与されている必要があります。 |
トークンの有効性 | サブジェクトトークンは有効期限が切れておらず、署名検証に合格する必要があります。 |
チェーンの深さ | サーバーは、無限の委任ループを防ぐために、交換の最大深度を強制します。 |
サポートされるトークンタイプ | アクセストークンからアクセストークンへの交換のみがサポートされています。 |
トークンの交換
ステップ 1:初期アクセストークンの取得
OAuth 2.0 認可コードフローを介して、呼び出し元クライアントの有効なアクセストークンを取得します。このトークンは、交換リクエストの subject_token になります。
すでに有効なアクセストークン (例えば、ユーザーのログインセッションからのトークン) を保持している場合は、ステップ 2 に進んでください。
ステップ 2:トークンエンドポイントの呼び出し
IDaaS トークンエンドポイントに POST リクエストを送信します。
エンドポイント
POST https://{domain}/api/v2/iauths_system/oauth2/token{domain} をご利用の IDaaS インスタンスのドメイン (例:example.jp.idaas.com) に置き換えます。
パラメーター
パラメーター | タイプ | 必須 | 例 | 説明 |
grant_type | String | はい | urn:ietf:params:oauth:grant-type:token-exchange |
|
subject_token | String | はい | <subject_token> | エンドユーザーの ID を表すアクセストークン。 |
subject_token_type | String | はい | urn:ietf:params:oauth:token-type:access_token |
|
requested_token_type | String | いいえ | urn:ietf:params:oauth:token-type:access_token | 発行するトークンのタイプ。デフォルトは |
scope | String | はい | mcp-server|user:read | 新しいトークンの権限。フォーマット: |
audience | String | いいえ | mcp-server | ターゲットサービスの論理名。 |
client_id | String | はい | <client_id> | 呼び出し元アプリケーションの OAuth クライアント ID。 |
client_secret | String | はい | <client_secret> | 呼び出し元アプリケーションの OAuth クライアントシークレット。 |
リクエスト例
curl -X POST 'https://{domain}/api/v2/iauths_system/oauth2/token' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
--data-urlencode 'subject_token=<subject_token>' \
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:access_token' \
--data-urlencode 'scope=mcp-server|user:read' \
--data-urlencode 'audience=mcp-server' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>'レスポンス例
{
"access_token": "eyJraWQiOiJBVVRI...xxxx",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600,
"expires_at": 1772605468,
"scope": "user:read"
}レスポンスフィールド
フィールド | タイプ | 説明 |
access_token | String | 新しく発行されたアクセストークン。 |
issued_token_type | String | 発行されたトークンのトークンタイプ URN。 |
token_type | String | 常に |
expires_in | Integer | トークンの有効期間 (秒単位)。 |
expires_at | Integer | トークンが失効する UNIX タイムスタンプ。 |
scope | String | 付与された権限スコープ。 |
エラーコード
HTTP ステータス | エラー | 原因 | 修正 |
400 | invalid_grant |
|
|
400 | invalid_request | 必須パラメーターが欠落しているか、形式が不正であるか、サブジェクトトークンが無効です。 | すべての必須パラメーターが存在し、サブジェクトトークンの有効期限が切れていないことを確認します。 |
400 | invalid_target | オーディエンスまたはスコープが認識されません。 |
|
401 | unauthorized_client | クライアント認証に失敗しました。 |
|
ステップ 3:ターゲットサービスの呼び出し
ターゲットリソースサーバーを呼び出す際に、新しいトークンを Authorization ヘッダーで渡します。
curl -X GET 'https://<resource_server>/api/protected-resource' \
-H 'Authorization: Bearer <access_token>'プレースホルダーを実際の値に置き換えます。
<resource_server>:ターゲットサービスのドメイン。<access_token>:ステップ 2 で返されたトークン。
例:エージェントから MCP への委任
ユースケース
ある会社が旅行計画エージェントと人事 (HR) MCP サービスを運用しています。従業員がエージェントに旅行の計画を依頼すると、エージェントは人事サービスから従業員の職位と出張予算を取得する必要があります。
トークン交換を使用すると、エージェントは従業員のトークンを人事 MCP サービスにスコープ指定されたトークンに交換します。従業員は再度ログインを求められることはなく、人事側は誰がリクエストを行っているかを正確に把握できます。
ロールのマッピング
RFC 8693 のロール | この場合 |
フロントサービス | 旅行システム (Web アプリ) |
リソースサーバー A | 旅行計画エージェント |
リソースサーバー B | HR MCP サービス |
認可サーバー | IDaaS |
得られるメリット
最小権限アクセス:交換されたトークンは、エージェントが人事サービスで必要とする権限のみを付与します。
追加のログイン不要:元のユーザー ID はチェーン全体を通じて引き継がれます。
完全な監査証跡:すべてのホップが記録され、追跡可能です (下記参照)。
監査とトラブルシューティング
コンソールでの交換ログの表示
すべてのトークン交換リクエスト (成功、失敗を問わず) は、IDaaS コンソールの Log > Call Logs に、イベントタイプ [トークン交換] として記録されます。各エントリには以下が記録されます。
交換をリクエストしたクライアント。
サブジェクト (エンドユーザーアカウント)。
サブジェクトトークン ID と関連メタデータ。
JWT での委任チェーンの追跡
IDaaS トークン交換によって生成されるすべてのトークンは、署名付きの JWT です。カスタムクレーム _idaas_imp には完全な委任チェーンが埋め込まれているため、どのトークンをデコードしても、どのクライアントが関与したかを正確に確認できます。
デコードされたペイロード (3 ホップチェーン)
{
"sub": "user_xxxxxxxxxxxxxxxxxxxx",
"scope": "user:read",
"jti": "AT_03",
"iss": "https://{domain}/api/v2/iauths_system/oauth2",
"iat": 1772604268,
"nbf": 1772604268,
"exp": 1772605468,
"aud": "mcp-server",
"client_id": "app_03",
"_idaas_iid": "idaas_xxxxxxxxxxxxxxxxxxxx",
"_idaas_tag": "user-auth",
"_idaas_imp": {
"jti": "AT_02",
"client_id": "app_02",
"_idaas_imp": {
"jti": "AT_01",
"client_id": "app_01"
}
}
}チェーンの読み方
フィールド | 意味 |
| 現在のトークン。最新の交換で |
| この交換で使用されたサブジェクトトークン。 |
| 元のトークン。直接のユーザーログインを介して |