送信者拘束トークン(DPoP / mTLS)とリフレッシュトークンローテーション
概要
通常の Bearer トークンは「持っている人なら誰でも使える」ため、盗まれると攻撃者がそのまま悪用できます。 これを防ぐ仕組みが、トークンを特定のクライアントの鍵に紐付ける送信者拘束(sender-constrained) トークンです。実現方式には DPoP と mTLS の2つがあります。
また、長命なリフレッシュトークンの保護にはローテーションが併用されます。OAuth 2.1 / セキュリティ BCP は、トークンをブラウザ/端末に持つパブリッククライアントに対して、 リフレッシュトークンを「ローテーション」または「送信者拘束」のいずれかにすることを求めています。
BFF パターンのようにトークンをサーバー側に保持する場合、そもそも 盗まれるトークンがクライアントに存在しないため、DPoP も mTLS も不要です。送信者拘束が問題になるのは、 端末側にトークンを持たざるを得ないパブリッククライアント(ネイティブモバイルアプリ等)です。
Bearer トークンの弱点
Bearer トークンには「所持=使用権」という前提があり、トークン自体に「誰のものか」という束縛がありません。 送信者拘束トークンは、ここに「鍵の所有証明」を加えます。
mTLS(相互 TLS)— RFC 8705
クライアントが TLS クライアント証明書を提示し、その証明書にトークンを紐付ける方式です。
トークンには証明書のサムプリント(cnf クレームの x5t#S256)が埋め込まれ、リソースサーバーは
TLS 接続で提示された証明書と一致するかを検証します。
- メリット:TLS レイヤーで完結し、堅牢。
- デメリット:PKI(証明書の発行・配布・失効)が必要で運用が重い。パブリッククライアントには不向き。
DPoP(Demonstrating Proof-of-Possession)— RFC 9449
クライアントが鍵ペアを自前で生成し、リクエストごとに署名付きの **DPoP proof(JWT)**を
DPoP ヘッダで添えます。トークンには公開鍵のサムプリント(cnf.jkt)が紐付き、リソースサーバーは
proof の署名がそのトークンに紐づく鍵で行われたことを検証します。
POST /resource
Authorization: DPoP <access_token>
DPoP: <proof-jwt> # htm(メソッド), htu(URL), iat, jti を含み、クライアント秘密鍵で署名
access_token の cnf: { "jkt": "<公開鍵のSHA-256サムプリント>" }
- メリット:PKI 不要・軽量。SPA・モバイル・パブリッククライアントに適する。
- デメリット:クライアント/サーバー双方に proof 生成・検証の実装が必要。
DPoP vs mTLS 比較
| 観点 | DPoP (RFC 9449) | mTLS (RFC 8705) |
|---|---|---|
| 拘束対象 | アプリ生成の鍵ペア | TLS クライアント証明書 |
| PKI | 不要 | 必要 |
| 実装の重さ | 軽量(アプリレイヤー) | 重い(インフラ/証明書管理) |
| 向くクライアント | パブリック(モバイル/SPA) | システム間/高保証環境 |
| 一般的な推奨 | 手軽でパブリック向き | 強固だが運用コスト大 |
リフレッシュトークンのローテーション
リフレッシュトークンを使うたびに新しいリフレッシュトークンを発行し、古いものを失効させる方式です。
- もし古い(使用済み)リフレッシュトークンが再提示されたら、それは漏洩・複製のサインとみなし、 トークンファミリー全体を失効させる(再利用検知)。
- 送信者拘束ではないが、漏洩時の被害窓を最小化できる。
パブリッククライアントの要件(OAuth 2.1)
OAuth 2.1 / セキュリティ BCP は、パブリッククライアントのリフレッシュトークンに対し、次のいずれかを 必須としています。
- ローテーション(再利用検知付き)
- 送信者拘束(DPoP または mTLS)
いつ何を使うか
- Web(ブラウザ)アプリ:BFF でサーバー側保持 → 拘束不要(最も簡単)。
- ネイティブモバイル/SPA(パブリック):端末にトークンを持つため、ローテーションを基本とし、 さらに強固にするなら DPoP による送信者拘束を検討。
- 高保証なシステム間連携:mTLS を選択肢に。
まとめ
- Bearer トークンは「所持=使用権」なので、盗まれると再利用される。
- 送信者拘束トークンはトークンを鍵に紐付け、盗難時の再利用を防ぐ。DPoP(PKI 不要・軽量)と mTLS(高保証・重い)がある。
- リフレッシュトークンローテーションは再利用検知により漏洩被害を最小化する。
- トークンをサーバー側に持てば拘束は不要。端末側に持つパブリッククライアントでこそ、ローテーション/ DPoP が重要になる。