メインコンテンツへスキップ
On-Behalf-Of (OBO) トークン交換 (RFC 8693) を使用すると、中間層サービスがダウンストリーム API を呼び出す際に、ユーザーの ID と権限を維持できます。 アプリケーションがダウンストリーム API を呼び出す必要がある場合は、次の方法を使用できます。
  • Client Credentials Flow: アプリケーションは自分自身のために動作し、自身として認証されます。リクエストがユーザーによって開始された場合でも、そのコンテキストは失われます。ダウンストリームサービスが認識できるのは、呼び出し元アプリケーションの ID のみです。
  • On-Behalf-Of (OBO) トークン交換: アプリケーションはユーザーに紐づくスコープを持つトークンを受け取り、それを新しいトークンに交換してダウンストリームサービスを呼び出せます。これにより、元のエンドユーザーの ID とコンテキストが呼び出しチェーン全体を通して維持されます。
たとえば、ユーザーが Service A の呼び出しをトリガーし、その後 Service A が Service B を呼び出す場合、OBO トークン交換を使うと、Service A はユーザーのアクセストークンを次のような新しいトークンに交換できます。
  • 元のユーザーの ID と権限を維持する
  • Service B 向けに限定されたスコープを持つ
  • Service B がエンドユーザーに基づいて認可を判断できるようにする
OBO トークン交換では post-login Action trigger がトリガーされ、次のようになります。 標準的なログインフローと同様に、ダウンストリーム API 呼び出しで返されるスコープは、ユーザーの ロールベースアクセス制御 (RBAC) ポリシーに基づきます。
Auth0 for AI Agents アドオンを購入すると、OBO トークン交換では、ご利用のサブスクリプションティアにおける Authentication API の最大レート制限を利用できます。たとえば、Private Cloud 100 RPS を利用している場合、30 RPS の OBO トークン交換のレート制限を超えて、OBO トークン交換リクエストに 100 RPS の全容量を使用できます。Authentication API の上限は共有されており、ログイン、トークンのリフレッシュ、トークン交換を含むすべての Authentication API リクエストを合算した全体の上限として機能します。詳細については、テクニカルアカウントマネージャーにお問い合わせください。

ユースケース

OBO Token Exchange の一般的なユースケースには、次のようなものがあります。
  • ユーザーの代わりにファーストパーティ API を呼び出す必要がある MCP サーバー
  • ユーザーの代わりにダウンストリームサービスを呼び出す必要があるマイクロサービス
アプリケーションからユーザーの代わりにサードパーティ API を呼び出せるようにするには、Token Vault を使用します。

仕組み

OBO トークン交換では、中間層サービスが受信したユーザー トークンを、ダウンストリーム サービス向けのスコープを持つ新しいトークンに交換できます。この新しいトークンは、元のユーザーの識別情報を保持したまま、JSON Web Token (JWT) ペイロード内で経由したサービスの連鎖を追跡します。

例: MCP サーバーがファーストパーティ API を呼び出す

ユーザーが Auth0 を使用してクライアントアプリケーションに認証され、その後そのアプリケーションが MCP サーバーを呼び出し、さらに MCP サーバーがファーストパーティ API を呼び出す必要があります。

ステップ 1: ユーザー認証

ユーザーがログインすると、Auth0 は JWT ペイロードに次のクレームを含む、MCP サーバー用のスコープが付与されたアクセストークンを発行します。
{
  "sub": "auth0|user123",
  "aud": "https://mcp-server.example.com",
  "azp": "spa_client_id" // トークンのプロファイルによって "client_id" になる場合もある
}
クレーム説明
subauth0|user123エンドユーザーのID
audhttps://mcp-server.example.comMCP サーバー向けのスコープが設定されたトークン
azp (or client_id depending on the アクセストークンプロファイル)spa_client_idトークンを要求したクライアントアプリケーション

ステップ 2: OBO 交換

OBO トークン交換を使用すると、MCP サーバーはユーザーのトークンを Auth0 に提示し、ファーストパーティ API 用のスコープが付与されたアクセストークンを要求します。Auth0 は、次のクレームを含む、その API 用にスコープが付与された新しいアクセストークンを発行します。
{
  "sub": "auth0|user123",
  "aud": "https://first-party-api.example.com",
  "azp": "mcp_server_client_id", // またはトークンプロファイルによっては "client_id"
  "act": {
    "sub": "mcp_server_client_id",
    "act": {
      "sub": "spa_client_id"
    }
  }
}
クレーム説明
subauth0|user123同一のユーザー ID が維持される
audhttps://first-party-api.example.comファーストパーティ API を対象とするトークン
azp (or client_id depending on the アクセストークンプロファイル)mcp_server_client_idトークンを要求したクライアント (トークン交換を実行した MCP サーバー)
act{"sub": "mcp_server_client_id",
"act": {"sub": "spa_client_id"}}
関与したすべてのアクターを示す委任チェーン

act クレーム

act (actor) クレームは、委任チェーン全体を追跡します。各 act レベルはコールチェーン内のサービスを表し、最も外側の act.sub は、現在のアクター、つまりトークン交換を実行した主体を識別します。 この例では、次のとおりです。
  • 最も外側の act.sub: mcp_server_client_id (直前にトークン交換を行った MCP サーバー)
  • ネストされた act.sub: spa_client_id (元のクライアントアプリケーション)
azp クレームは最も外側の act.sub の値と一致し、直近でトークン交換を行ったサービスを識別している必要があります。 ファーストパーティ API が別のダウンストリームサービス (https://calendar-api.acme.com) を呼び出す場合、委任チェーンはさらに拡張されます。
{
  "sub": "auth0|user123",
  "aud": "https://calendar-api.acme.com",
  "azp": "first_party_api_client_id",
  "act": {
    "sub": "first_party_api_client_id",
    "act": {
      "sub": "mcp_server_client_id",
      "act": {
        "sub": "spa_client_id"
      }
    }
  }
}
委任チェーンは、ネストされた階層を 5 レベルまでに制限しています。サブジェクトトークンにすでに 5 つの act ネストレベルがある場合、OBO トークン交換は失敗します。
400 Bad Request
{
  "error": "invalid_request",
  "error_description": "Delegation chain (`act` claim) depth exceeds the maximum allowed limit of 4"
}
API 呼び出しのたびに新しいトークンを要求するのではなく、アクセストークンはトークンの有効期間中キャッシュしてください。アクセストークンは有効期限が切れるまで再利用できます。トークンの取得を繰り返すと、リソースを無駄にし、レイテンシが増加し、レート制限に達する可能性があります。

ユーザー > MCP サーバー > API フロー

次の図は、MCP サーバー がユーザーに代わってファーストパーティ API を呼び出す際の、エンドツーエンドの OBO トークン交換フローを示しています。
  1. ユーザー認証: ユーザーはクライアントアプリケーションで認証されます。Auth0 認可サーバーは、MCP サーバー向けのスコープを持つトークン A を発行します。
  2. 初回リクエスト: クライアントアプリケーションは MCP サーバーを呼び出し、Authorization: Bearer ヘッダーでトークン A を渡します。
  3. 検証とトークン交換: MCP サーバーはトークン A を受信して検証し、その後 Auth0 認可サーバーの /oauth/token エンドポイントに渡します。OBO トークン交換を使用して、MCP サーバーはトークン A を subject_token として提示し、ファーストパーティ API 用の新しいトークンを要求します。
  4. トークン発行: Auth0 認可サーバーはトークン B を発行します。トークン B の sub (ユーザー ID) はトークン A と同じですが、aud (オーディエンス) はファーストパーティ API になります。
  5. ダウンストリーム呼び出し: MCP サーバーはトークン B を使用してファーストパーティ API を呼び出します。API はトークン B を検証し、そのリクエストが元のユーザーに代わって正当に行われていることを確認します。

ユーザー > API1 > API2 > API3

次の図は、マイクロサービスの連鎖がユーザーに代わって下流のサービスを呼び出すエンドツーエンドのフローを示しています。
  1. ユーザー認証: ユーザーはクライアントアプリケーションに正常に認証されます。Auth0 認可サーバーは、API1 向けのスコープを持つ Token A を発行します。
  2. 初回リクエスト: クライアントアプリケーションは API1 を呼び出し、Authorization: Bearer ヘッダーで Token A を渡します。
  3. API1 から API2 への委任: API1 は Token A を受け取って検証した後、Auth0 認可サーバーの /oauth/token エンドポイントに送信します。OBO トークン交換を使用して、API1 は Token A を subject_token として提示し、API2 用の新しいトークンを要求します。
  4. トークンの発行: Auth0 認可サーバーは API1 に新しいアクセストークン Token B を付与します。Token B の sub (ユーザー ID) は Token A と同じですが、aud (オーディエンス) は API2 になります。
  5. ダウンストリーム呼び出し: API1 は Token B を使用して API2 にリクエストを送信します。
  6. API2 から API3 への委任: API2 は Token B を受け取って検証した後、Auth0 認可サーバーの /oauth/token エンドポイントに送信します。OBO トークン交換を使用して、API2 は Token B を subject_token として提示し、API3 用の新しいトークンを要求します。
  7. トークンの発行: Auth0 認可サーバーは API2 に新しいアクセストークン Token C を付与します。Token C の sub (ユーザー ID) は Token A および Token B と同じですが、aud (オーディエンス) は API3 になります。
  8. ダウンストリーム呼び出し: API2 は Token C を使用して API3 にリクエストを送信します。API3 は Token C を検証し、そのリクエストが元のユーザーに代わって正当に行われていることを確認します。

前提条件

OBO トークン交換を使用できるのは、リソースサーバーに関連付けられた Custom API クライアントのみです。Custom API クライアントは、リソースサーバーと同じ識別子を共有している場合、そのリソースサーバーに関連付けられます。 Custom API クライアントには、次の要件があります。
  • app_typeresource_server に設定します。
  • resource_server_identifier を有効なリソースサーバー、つまり https://my-api.example.com に設定します。Auth0 は、認可リクエストでリソースサーバー識別子を audience パラメーターとして使用します。
Custom API クライアントはファーストパーティ クライアントであるため、ファーストパーティ クライアントがアクセスする必要がある API については、必ずユーザーの同意をスキップしてください。

Custom API クライアントを作成する

Auth0 Dashboard または Management API を使用して、Custom API クライアントを作成できます。
Auth0 Dashboard で Custom API クライアントを作成するには、次の手順に従います。
  1. Applications > APIs に移動し、バックエンド API を選択します。
My Test OBO API
  1. Add Application を選択し、アプリケーション名を入力します。
  2. Add を選択します。
アプリケーションが正常に作成されたら、Configure Application を選択して確認し、Application Properties までスクロールします。Application TypeCustom API Client です。
My Test OBO API

クライアントグラントを作成

アクセスを認可するには、Custom API クライアントとダウンストリーム API の間に、ユーザー委任のクライアントグラントを作成する必要があります。
  1. Applications > Applications に移動し、Custom API クライアントを選択します。
  2. API Access で、対象のリソースサーバー (例: https://my-api.example.com) を見つけて Edit を選択します。
  3. User-Delegated AccessGrant Access を選択し、付与する権限を選択するか、Always grant all permissions を選択します。
  4. Save を選択します。

OBO トークン交換を設定する

OBO トークン交換グラントを使用するように Custom API クライアントを設定する方法を説明します。
  1. Applications > Applications に移動し、Custom API クライアントを選択します。
  2. Token Exchange で、On-Behalf-Of Token Exchange をオンにします。
  3. Save を選択します。
My Test OBO API

OBOトークン交換を実行する

OBOトークン交換を実行するには、auth0-api-jsauth0_api_python、または Authentication API を使用できます。
API 呼び出しのたびに新しいトークンを要求するのではなく、アクセストークンはトークンの有効期間中キャッシュしてください。アクセストークンは有効期限が切れるまで再利用できます。トークン交換を繰り返すと、リソースの無駄遣いになり、レイテンシが増加し、レート制限に達する可能性があります。
始める前に、auth0-api-js ライブラリとその依存関係をインストールしておいてください。まず、MCP サーバーの認証情報を使用して ApiClient を初期化します。
import { ApiClient } from '@auth0/auth0-api-js';

const apiClient = new ApiClient({
  domain: 'YOUR_AUTH0_DOMAIN',
  audience: 'YOUR_MCP_SERVER_AUDIENCE',
  clientId: 'YOUR_CLIENT_ID',
  clientSecret: 'YOUR_CLIENT_SECRET',
});
次に、getTokenOnBehalfOf() メソッドを使用してトークン交換を行います。
const result = await apiClient.getTokenOnBehalfOf(accessToken, {
  audience: 'YOUR_DOWNSTREAM_API_AUDIENCE',
  scope: 'read:private',  // 省略可能
});
getTokenOnBehalfOf() は、次を含むオブジェクトを返します。
  • accessToken: ダウンストリーム API 用の新しいトークン
  • scope: 付与されたスコープ
  • expiresIn: トークンの有効期間 (秒)

組織のサポート

ユーザーが組織経由で認証されると、アクセストークンには org_id クレームが含まれます。OBO トークン交換では、この組織コンテキストが委任チェーン全体で維持されます。 Auth0 が組織に関連付けられたアクセストークンを含む OBO トークン交換リクエストを受信すると、次の点を検証します。
  • org_id がテナント内に存在すること
  • ユーザー (sub で識別される) がその組織のメンバーであること
検証に失敗した場合、Auth0 はトークン交換リクエストを拒否します。検証に成功すると、Auth0 は次のような新しいアクセストークンを発行します。
  • 元のトークンと同じ org_id クレームを含む
  • 同じ組織固有の RBAC ポリシーを適用する
  • post-login Actions triggerevent.organization プロパティを通じて組織コンテキストを利用できるようにする