Skip to main content
On-Behalf-Of (OBO) Token Exchange (RFC 8693) を使用すると、中間層サービスはダウンストリームAPIの呼び出し時に、ユーザーのIDと権限を保持できます。 アプリケーションがダウンストリームAPIを呼び出す必要がある場合は、次の方法を使用できます。
  • Client Credentials Flow: アプリケーションは自身の代理として動作し、自身として認証されます。リクエストがユーザーによって開始された場合でも、そのコンテキストは失われます。ダウンストリームサービスが認識できるのは、呼び出し元アプリケーションのIDだけです。
  • On-Behalf-Of (OBO) Token Exchange: アプリケーションはユーザーにスコープが付与されたトークンを受け取り、それを新しいトークンに交換してダウンストリームサービスを呼び出せます。これにより、元のエンドユーザーのIDとコンテキストが呼び出しチェーン全体で保持されます。
たとえば、ユーザーが Service A への呼び出しをトリガーし、その後 Service A が Service B を呼び出す場合、OBO token exchange を使用すると、Service A はユーザーのアクセストークンを次のような新しいトークンに交換できます。
  • 元のユーザーのIDと権限を維持する
  • Service B 用に特化したスコープが設定されている
  • Service B がエンドユーザーに基づいて認可の判断を行えるようにする
OBO token exchange では、post-login Action トリガーが実行されます。ここで: 標準的なログインフローと同様に、ダウンストリームAPI呼び出しに対して返されるスコープは、ユーザーの Role-Based Access Control (RBAC) ポリシーに基づきます。
Auth0 for AI Agents アドオンを購入すると、OBO token exchange に対して、ご利用中のサブスクリプションティアにおける Authentication API の最大レート制限を使用できます。たとえば、Private Cloud 100 RPS を利用している場合、OBO token exchange の 30 RPS というレート制限を超えて、OBO token exchange リクエストに対して最大 100 RPS の容量を利用できます。Authentication API の制限は共有されており、ログイン、トークンの更新、トークン交換を含む、すべての Authentication API リクエストを合算した全体の上限として機能します。詳細については、Technical Account Manager にお問い合わせください。

ユースケース

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

仕組み

OBO token exchange により、中間層サービスは受信したユーザー token を、downstream service 向けの scope を持つ新しい token に交換できます。この新しい token は元のユーザーの ID を保持しながら、JSON Web Token (JWT) の payload 内で、関与したサービスの連鎖を追跡します。

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

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

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

ユーザーがログインすると、Auth0 は JWT のペイロードに次のクレームを含む、MCP サーバー向けのスコープが設定されたアクセストークンを発行します。

ステップ 2: OBO 交換

OBOトークン交換を使用して、MCPサーバーはユーザーのトークンをAuth0に提示し、ファーストパーティAPI向けのスコープが設定されたアクセストークンをリクエストします。Auth0は、次のクレームを含む、API向けにスコープが設定された新しいアクセストークンを発行します。

act クレーム

act (actor) クレーム は、委譲チェーン全体を追跡します。各 act レベルは呼び出しチェーン内のサービスを表し、最も外側の act.sub は、token exchange を実行した現在のアクターを識別します。 この例では:
  • 最も外側の act.sub: mcp_server_client_id (直前に token exchange を行った MCP サーバー)
  • ネストされた act.sub: spa_client_id (元のクライアントアプリケーション)
azp クレーム は最も外側の act.sub の値と一致し、直近で token exchange を実行したサービスを示す必要があります。 ファーストパーティ API が別のダウンストリームサービス (https://calendar-api.acme.com) を呼び出す場合、委譲チェーンはさらに延びます:
委譲チェーンは5段階までのネストに制限されています。exchange によって現在のクライアントがさらに1段階として追加されるため、subject token にすでに act のネストが4段階ある場合、OBO トークン交換は失敗します。
API呼び出しのたびに新しいトークンを要求するのではなく、アクセストークンは有効期限が切れるまでキャッシュして使ってください。アクセストークンは有効期限内であれば再利用できるため、トークン交換を繰り返すと、リソースの無駄遣いになり、待ち時間が増え、レート制限にかかるおそれがあります。

User > MCPサーバー > API フロー

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

ユーザー > API1 > API2 > API3

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

前提条件

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

カスタム API クライアントを作成

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

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

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

OBO token exchange を設定する

OBO token exchange グラントを使用してカスタム API クライアントを設定する方法を説明します。
  1. アプリケーション > アプリケーション に移動し、カスタム API クライアントを選択します。
  2. Token Exchange で、On-Behalf-Of Token Exchange をオンにします。
  3. Save を選択します。
My Test OBO API

OBO token exchange を実行する

OBO token exchange を実行するには、auth0-api-js、auth0_api_python、または Authentication API を使用します。
API 呼び出しのたびに新しいトークンをリクエストするのではなく、アクセストークンは有効期限が切れるまでキャッシュしてください。アクセストークンは期限切れになるまで再利用できます。トークン交換を繰り返すと、リソースの無駄遣いになり、レイテンシが増加し、レート制限に達するおそれがあります。
始める前に、auth0-api-js ライブラリと、その依存関係がインストールされていることを確認してください。まず、MCP サーバーの資格情報を使って ApiClient を初期化します。
次に、getTokenOnBehalfOf() メソッドを使用してトークン交換を行います。
getTokenOnBehalfOf() は、次のプロパティを含むオブジェクトを返します。
  • accessToken: downstream API 用の新しいトークン
  • scope: 付与されたスコープ
  • expiresIn: トークンの有効期限 (秒)

トークンバインディング

DPoP または mTLS を使用してトークンが送信者に制約されている場合、キーまたは証明書の正当な保有者のみが所有を証明してトークンを使用できます。OBO 交換中、トークンは中間層サービスが保持します。Auth0 は、中間層サービスが元の保有者のキーまたは証明書を保持していることを暗号学的に検証できないため、交換時に元のトークンのバインディングを再検証しません。中間層サービスには、次の責任があります。
  • トークンバインディングの検証
  • 新しいトークンのバインディング
  • DPoP と mTLS 間でバインディングメカニズムを切り替える仕組みの管理
トークンバインディングの検証は中間層サービスの責任です。バインディングとは、トークン保有者が元の保有者のキーまたは証明書を所有していることを示す暗号学的証明です。バインドされたトークンを交換する前に、元のトークンのバインディングが検証済みであることを確認してください。
  • DPoP: 受信した DPoP proof の jwk の JWK SHA-256 thumbprint を計算し (RFC 7638 に従う) 、サブジェクトトークンの cnf.jkt クレーム と一致することを検証します。Auth0 はトークン交換中にこのチェックを実行しません。
  • mTLS: クライアント証明書の DER エンコーディングの SHA-256 thumbprint を base64url エンコードし、サブジェクトトークンの cnf.x5t#S256 クレーム と一致することを検証します。
バリデーションに失敗した場合は、交換を試行せずに request を拒否してください。 新しいトークンのバインディング: ダウンストリームリソースサーバーで送信者制約が有効または必須になっている場合、中間層サービスが有効な DPoP proof または mTLS 証明書を /oauth/token endpoint に提示すると、Auth0 は新たに発行する アクセストークン を送信者に制約します。 DPoP proof も mTLS 証明書も提示されない場合、Auth0 は元のサブジェクトトークンのバインディング status にかかわらず、バインドされていない bearer token を発行します。 バインディングメカニズムの移行と capabilities の不一致: 中間層サービスは、新しいメカニズムに必要な資格情報 (たとえば、プロビジョニング済みの mTLS 証明書) を保有していれば、OBO 交換中にバインディングメカニズムを切り替えられます (たとえば、DPoP から mTLS へ) 。新たに発行されるトークンには、新しいバインディングタイプが反映されます。 交換前に、ダウンストリーム API が提示するバインディングメカニズムをサポートしていることを確認してください。Auth0 はメカニズムの互換性を検証せず、互換性にかかわらずトークンを発行します。ダウンストリーム API が提示されたメカニズムをサポートしていない場合、runtime でトークンを拒否します。メカニズム間の調整ができない場合は、交換を試行せず、代わりに呼び出し元へ error を返してください。 DPoP nonce: 元のサブジェクトトークンが、サーバー発行 nonce を使用する DPoP により public client (SPA やモバイルアプリなど) に発行された場合、中間層サービスは /oauth/token endpoint で再バインディングするための有効な nonce を持っていない可能性があります。この場合、Auth0 は DPoP-Nonce response header に新しい nonce を含む use_dpop_nonce error を返します。新しい DPoP proof でその nonce を使用して request を再試行してください。
元のサブジェクトトークンが送信者に制約されているにもかかわらず、中間層サービスがバインディング資格情報 (DPoP proof または mTLS 証明書) を /oauth/token エンドポイントに提示しない場合、Auth0 はリクエストを拒否しません。代わりに、エラーを示さずにバインドされていない bearer token を発行します。ダウンストリーム API は Proof of Possession なしでこのトークンを受け入れるため、傍受されると再利用される可能性があります。ダウンストリームのリソースサーバーが送信者に制約された tokens を必要とする場合は、バインドされていない token を forward しないでください。拒否して、呼び出し元にエラーを返してください。

Organizations のサポート

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