Skip to main content
Demonstrating Proof-of-Possession (DPoP) は、非対称暗号方式とアプリケーション層の 、および (JWT) を使用して、をクライアントに結び付ける、つまり 送信者制約 を適用するための OAuth 2.0 framework extension です。DPoP により、秘密キーを保持する、アクセストークンを要求したクライアントアプリケーションのみがそのトークンを使用できるようになります。これにより、盗まれたトークンの悪用を防止します。 DPoP は公開鍵/秘密鍵を使用して、署名付き JSON Web トークン (JWT) として DPoP Proof を作成します。DPoP Proof には次のものが含まれます。
  • クライアントの公開鍵 (jwk) 。
  • メソッド (htm) と URI (htu) を含む、アクセストークンrequestを参照するpayload。
  • クライアントの秘密キーを使用して作成された署名。
  • リプレイ防止のための一意の ID (jti) 。
  • API request ごとに含まれる、アクセストークンの base64url エンコードされた SHA-256 ハッシュ (ath) 。
  • 任意: の場合、クライアントアプリケーションが最近 DPoP Proof JWT を生成したことを保証するための nonce claim。
クライアントアプリケーションは、アクセストークンrequestで DPoP Proof JWT を Auth0 の に送信します。Auth0 Authorization Server が DPoP Proof JWT をvalidateした後、発行されたアクセストークンをクライアントの公開鍵に結び付けます。

一般的な利用例

代表的な DPoP の利用例をいくつか紹介します。
  • Single Page Applications (SPAs) and mobile applications: 公開クライアントである SPA やモバイルアプリケーションには、バックエンドサーバーのような、 を安全に保存できる信頼された機密環境がありません。そのため、トークン盗難に対して脆弱です。DPoP は、アクセストークンをクライアントアプリケーションの公開キーに結び付けて DPoP Proof JWT を作成することで、このセキュリティ脆弱性に対処します。クライアントアプリケーションは、自身の秘密キーで DPoP Proof JWT に署名し、認可リクエストで送信します。Auth0 Authorization Server は DPoP Proof JWT を検証し、有効であれば、発行するアクセストークンをクライアントの公開キーに結び付けます。
  • Third-party API integrations: クライアントアプリケーションと連携した AI エージェントが、ユーザーに代わって DPoP Proof JWT を使用してサードパーティ API を呼び出す場合、 は、そのリクエストが権限のない第三者ではなく AI エージェントから送信されたものであることを、暗号学的に検証できます。

サポートされているアプリケーションのグラントタイプ

Auth0 は、DPoP を使用した送信者拘束向けに、次のアプリケーションのグラントタイプをサポートしています。

仕組み

次のシーケンス図は、Auth0 DPoP フローの概要を示しています。
  1. Auth0 Authorization Server にアクセストークンをリクエストする際、クライアントアプリケーションは一意の暗号鍵ペアを生成し、公開キーを使って対応する秘密キーを保有していることを証明します。
  2. クライアントアプリケーションは DPoP Proof JWT を生成し、それを Auth0 Authorization Server の /token エンドポイントに送信します。
  3. Auth0 Authorization Server は DPoP Proof JWT を検証し、有効であればアクセストークンを発行して、クライアントの公開キーに紐付けます。
  4. Customer API を呼び出す前に、クライアントアプリケーションは新しい DPoP Proof JWT を生成し、トークンに紐付けられた秘密キーを保有していることを証明します。クライアントアプリケーションは、DPoP Proof JWT と sender-constrained アクセストークンをリソースサーバーに送信します。
  5. リソースサーバーは DPoP Proof JWT を検証し、トークンの正当な所有者、つまり元のクライアントアプリケーションだけが、それを使って保護されたリソースに正常にアクセスできることを確認します。リフレッシュトークンからアクセストークンをリクエストする場合、クライアントアプリケーションは新しい DPoP Proof JWT を生成し、リフレッシュトークンがクライアントの公開キーに紐付けられるようにします。

Auth0 で DPoP を使用してトークンに送信者拘束を適用する

次の図は、Auth0 で DPoP を使用してトークンに送信者拘束を適用するエンドツーエンドのフローを示しています。
以下のセクションでは、実装用のコードサンプルとともに、Auth0 での DPoP フローを順を追って説明します。

前提条件

開始する前に、次の点を確認してください。
  • クライアントアプリケーションとリソースサーバーに対して、送信者拘束を設定していること。

ステップ1: クライアントアプリケーションがDPoPキーペアを生成する

DPoPでは、クライアントアプリケーションは非対称暗号のキーペアを生成する必要があります。Auth0は、ES256キーなどの楕円曲線暗号の使用をサポートしています。このキーペアはクライアントアプリケーションごとに固有のもので、たとえばハードウェアで保護されたキーストアに安全に保管する必要があります。 クライアントアプリケーションは秘密鍵を厳重に保持しつつ、ステップ2で「Proof of Possession」として機能するDPoP Proof JSON Web トークン (JWT) に公開鍵を含めます。

ステップ 2: クライアントアプリケーションが DPoP Proof JWT を作成する

Auth0 Authorization Server の /token エンドポイントに DPoP にバインドされたアクセストークンをリクエストする前に、クライアントアプリケーションは DPoP Proof JWT を作成する必要があります。DPoP Proof JWT は、クライアントの秘密キーで署名された JSON Web トークン (JWT) で、「Proof of Possession (所持証明) 」として機能します。 DPoP Proof JWT は、JWT ヘッダーと、トークンリクエストに関連するクレームを含むペイロードで構成されます。

JWTヘッダーのクレーム

JWT ペイロードクレーム

クライアントアプリケーションで DPoP Proof JWT を作成したら、Step 1 で生成した秘密キーを使って DPoP Proof JWT に署名します。 以下のコードサンプルは、クライアントアプリケーションで DPoP Proof JWT を作成して署名する方法を示しています。

ステップ 3: クライアントアプリケーションが DPoP-bound token をリクエストする

クライアントアプリケーションが Auth0 Authorization Server の /token エンドポイントに access token をリクエストする際は、リクエストの HTTP ヘッダーに DPoP Proof JWT を含めます。
以下は、DPoP Proof JWT が設定された DPoP HTTPヘッダーを含むアクセストークンリクエストの例です。
クライアントアプリケーションで DPoP バインド アクセストークンをリクエストする方法を実装するには、次のコードサンプルを使用します。このサンプルでは、以下を行います。
  1. 署名付き DPoP Proof JWT を使用して、DPoP HTTP ヘッダーに値を設定します。
  2. 署名付き DPoP Proof JWT を含む DPoP HTTP ヘッダーを、/token エンドポイントへのアクセストークンリクエストで送信します。
  3. Auth0 認可サーバーからのレスポンスを処理します。

パブリッククライアント

シングルページアプリケーション (SPA) やモバイルアプリなどのパブリッククライアントが DPoP にバインドされたアクセストークンをリクエストする場合、client secret やその他のクライアント認証パラメーターは使用できません。この場合、RFC 9449 に従い、Auth0 はクライアントアプリケーションが DPoP Proof JWT を直近で生成したことを確認するため、DPoP HTTP header 値が含まれていることを求めます。これは想定どおりの動作であり、認可サーバーが DPoP proof の新しさを確認し、その proof を使用できる時間を限定できるようにするためです。 パブリッククライアントが /token request を行う際に、DPoP HTTP headernonce 値を含めない場合、Auth0 は HTTP 400 コードと、次のようなエラーメッセージを返します。
Auth0 は、レスポンスヘッダーに DPoP-Nonce ヘッダーを含めます。これは、DPoP specification で定義されている標準の「challenge-response」フローに従ったものです。DPoP-Nonce ヘッダーの値を使用して DPoP proof を再生成し (Step 2 と同様) 、その値を含む nonce クレームを追加したうえで、/token エンドポイントへのリクエストを再送信する必要があります。 次のコードサンプルは、パブリッククライアントから nonce クレームを含む /token リクエストを送信し、その後再試行する際のエンドツーエンドのフローを示しています。

ステップ 4: Auth0 Authorization Server が DPoP Proof JWT を検証する

Auth0 Authorization Server はトークンリクエストを受信すると、次の処理を行います。
  • DPoP Proof JWT、その公開キー、署名を抽出します。
  • 提供された公開キーを使用して署名を検証します。
  • htmhtujti,iat の各クレームを検証します。
  • 有効であれば、アクセストークンを発行します。Auth0 Authorization Server は、確認用クレーム cnf をアクセストークンに含めます。cnf クレームには、DPoP Proof JWT から取得した公開キーの thumbprint (ハッシュ) が含まれます。これをアクセストークンに含めることで、Auth0 Authorization Server はそのアクセストークンを特定の公開キーに関連付けます。つまり、アクセストークンを “sender-constrains” します。
  • トークンレスポンスでは、Authorization ヘッダーの token_typeBearer ではなく DPoP に設定します。通常、アクセストークンを Authorization ヘッダーで渡す場合、token_typeBearer に設定されます。しかし、ここでは DPoP を使用して公開キーに関連付けられたアクセストークンを渡すため、代わりに DPoP に設定されます。
  • その後、Auth0 Authorization Server は DPoP sender-constrained アクセストークンをクライアントアプリケーションに発行します。

ステップ 5: クライアントアプリケーションが DPoP-bound token と DPoP Proof JWT を使用して API を呼び出す

DPoP を強制するリソースサーバーに対する API 呼び出しごとに、クライアントアプリケーションは DPoP-bound access token と新しい DPoP Proof JWT の両方を提示する必要があります。 DPoP は、すべての API リクエストで DPoP Proof JWT を必須にすることで、秘密キーを保持するクライアントアプリケーションだけがアクセストークンを使用できるようにします。 新しい API リクエストでは、クライアントアプリケーションは次のことを行います。
  1. 次のクレームを含む新しい DPoP Proof JWT を生成します。
  • htm クレームは、GETPOST などの API リクエストの HTTP メソッドです。
  • htu クレームは、API リクエストの URI です。
  • ath クレームは、ステップ 3 で受け取った DPoP-bound access token の base64url エンコードされた SHA-256 ハッシュです。
  1. クライアントの秘密キーを使って、新しい DPoP Proof JWT に暗号学的に署名します。
  2. DPoP 認証スキームを使用して、Authorization ヘッダーに DPoP-bound access token を含めます。
  1. 新たに生成した DPoP Proof JWT を DPoP HTTP ヘッダーに含めます:
DPoP HTTPヘッダーには、追加のathクレームを含める必要があります。athクレームは、発行されたアクセストークンのSHA256ハッシュをbase64urlエンコードしたものです。 リソースサーバーは次の処理を行います。
  • APIリクエストを受信し、アクセストークン、DPoP Proof JWT、公開キー、署名を抽出します。
  • jwkヘッダー内の公開キーを使用して、DPoP Proof JWTの署名を検証します。
  • htmhtujtiiatathの各クレームを検証します。
  • DPoP Proof JWTのjwkヘッダーで示された公開キーが、アクセストークン内のcnf.jktクレームによってアクセストークンに関連付けられた公開キーと一致することを検証します。
jtiのリプレイ保護の実装はリソースサーバーの責任です。すべてのAuth0 SDKsがデフォルトでjtiのリプレイ保護を強制するわけではありません。
すべてのチェックに成功した場合、リソースサーバーはリクエストを認可します。そうでない場合は、リクエストを拒否し、アクセスを拒否します。 次のコードサンプルでは、DPoPを使用してAuth0からアクセストークンをリクエストし、その後、DPoPにバインドされたアクセストークンを使用して/userinfoエンドポイントを呼び出します。

ステップ 6: DPoP を使用してトークンの更新を処理する

DPoP にバインドされたアクセストークンの有効期限が切れた場合は、新しいアクセストークンを取得するために を使用できます。リフレッシュトークンのリクエストには、元のトークンリクエストで使用したものと同じキーペアで生成した DPoP Proof JWT が必要です。 以下では、Auth0 における DPoP を使用したリフレッシュトークンのフローについて説明します。 クライアントアプリケーションは次を行います。
  • Auth0 認可サーバーの /token エンドポイントに、リフレッシュトークンのリクエストを送信します。
  • リフレッシュトークンのリクエスト用に DPoP Proof JWT を生成します (ステップ 2 と同様ですが、htmPOSThtu の URI です) 。
  • DPoP HTTP ヘッダーに DPoP Proof JWT を含めます。
Auth0 認可サーバーは次を行います。
  • DPoP Proof JWT を検証し (ステップ 4 と同様) 、新しい DPoP バインドアクセストークンを発行します。

重要な考慮事項

クライアントアプリケーションに DPoP を実装する際は、次の点を考慮してください。
  • 秘密キーのセキュリティ: DPoP 実装の安全性はクライアントの秘密キーの安全性に依存するため、不正アクセスから保護する必要があります。秘密キーは、ハードウェアに裏打ちされた領域で生成および保管し、エクスポート不可に設定する必要があります。
  • リプレイ保護 (jti** と dpop-nonce):** DPoP Proof JWT の jti クレームは、/userinfo エンドポイントなどの保護されたリソースに対するリプレイ攻撃の防止に役立ちます。Auth0 Authorization Server はレスポンスで DPoP-Nonce HTTP ヘッダーを返し、公開クライアントはリプレイ保護を強化するために、後続の DPoP Proof JWT にこれを nonce クレームとして含める必要があります。
  • レート制限: DPoP のチャレンジレスポンスフローでは、最初のリクエストの後にサーバーから提供された nonce を使って再試行が必要になる場合があるため、各やり取りは実質的に Auth0 テナントのレート制限 に対して 2 回のリクエストとしてカウントされます。アプリケーションのリクエスト量がこのオーバーヘッドを考慮していることを確認してください。
  • エラー処理: invalid_dpop_proofuse_dpop_nonce など、Auth0 Authorization Server またはリソースサーバーから返される DPoP 固有のエラーを処理するロジックは、お客様側で実装する必要があります。
  • クライアントの種類: クライアントシークレットを安全に保管できない Single Page Applications (SPAs) やモバイルアプリなどの公開クライアントには DPoP を使用してください。には、クライアントシークレットを持つバックエンドサービスなどが含まれます。DPoP はセキュリティをさらに強化しますが、これらにはすでに他の sender-constraining の仕組みがあります。
  • パフォーマンス: API 呼び出しごとに DPoP Proof JWT を生成して署名すると、わずかなオーバーヘッドが追加されるため、クライアントアプリケーションの暗号処理が効率的であることを確認してください。
  • キーのローテーション: セキュリティを強化するために、DPoP のキー ペアをローテーションする strategy を実装してください。同じセッションでは必ず同じキー ペアを使用してください。
  • 永続化: セッションを維持し、DPoP-bound access token を再利用する必要があるクライアントアプリケーション (長期間利用される SPA など) では、アプリケーションの再読み込み後も、最初に生成したキー ペアを安全に保存し、再取得できるようにしてください。新しいキー ペアが生成されたり、別のキー ペアが使用されたりすると、DPoP-bound access token は元のペアの公開キーに暗号学的に結び付けられているため無効になります。たとえば、ブラウザーの IndexedDB やモバイルアプリの安全なストレージにキー ペアを保存できます。

詳細はこちら