FAPI 2.0 解説 - API セキュリティの最新動向解説

## はじめに

FAPI とは、安全かつ相互運用可能な API 通信を実現するための標準規格を指しており、とりわけ医療分野・金融業界・電子政府といった高セキュリティが要求される業界において重要な役割を果たしています。OAuth 2.0 と OpenID Connect を基礎に置く FAPI 1.0 に始まり、今日ではその最新版である FAPI 2.0 にまで発展を遂げました。FAPI 2.0 では、最新のプロトコルを採用することでよりセキュアなデータ保護を可能とする一方で、従来よりも更にシンプルな実装が可能となりました。

## 構成要素

![スライド1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/2dbf01a7-b54d-d8f7-af5b-ab7e88a76491.png)

FAPI 2.0 は API セキュリティの向上を目的とし、包括的なフレームワークを導入しました。FAPI 2.0 は、大きく以下の 4 つの要素に分類されます:

### Security プロファイル
FAPI 2.0 の中核を成すプロファイルで、"PAR" や "DPoP" といった最新のセキュリティ仕様群を活用しています。このプロファイルは、かつて「Baseline プロファイル」と呼ばれていました。

### Message Signing プロファイル
OAuth 2.0 をベースとしたリクエスト・レスポンスに対して、「否認防止 (non-repudiation)」のメカニズムをサポートするためのプロファイルです。このプロファイルは、かつて「Advanced プロファイル」と呼ばれていました。

### 攻撃者モデル
API セキュリティを実現する上での潜在的リスクとその防止策を詳細に説明しています。

### グラントマネジメント
OAuth 2.0 を拡張し、クライアントアプリケーションに付与された権限を管理するための仕組みを定義しています。

## FAPI の歴史

![スライド2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/dff44d2d-b0e9-42d2-b8d0-7f87b550a96f.png)

### FAPI 1.0 Final (2021 年 3 月)

- [**Financial-grade API Security Profile 1.0 — Part 1: Baseline**](https://openid.net/specs/openid-financial-api-part-1-1_0-final.html)
- [**Financial-grade API Security Profile 1.0 — Part 2: Advanced**](https://openid.net/specs/openid-financial-api-part-2-1_0-final.html)

FAPI 1.0 に関する詳細については、「[実装者による Financial-grade API (FAPI) 解説](https://qiita.com/TakahikoKawasaki/items/83c47c9830097dba2744)」が参考になります。

### FAPI 2.0 Implementer’s Draft 1 (ID 1)

- [**FAPI 2.0 Baseline Profile**](https://openid.net/specs/fapi-2_0-baseline-ID1.html) (2021 年 7 月)
- [**FAPI 2.0 Attacker Model**](https://openid.net/specs/fapi-2_0-attacker-model-ID1.html) (2021 年 7 月)
- [**Grant Management for OAuth 2.0**](https://openid.net/specs/fapi-grant-management-ID1.html) (2021 年 7 月)
- [**FAPI 2.0 Message Signing Profile**](https://openid.net/specs/fapi-2_0-message-signing-ID1.html) (2023 年 3 月)

NOTE: 「**Advanced プロファイル**」は「**Message Signing プロファイル**」に改名されました。

### FAPI 2.0 Implementer’s Draft 2 (ID 2)

- [**FAPI 2.0 Security Profile**](https://openid.net/specs/fapi-2_0-security-profile-ID2.html) (2022 年 12 月)

- [**FAPI 2.0 Attacker Model**](https://openid.net/specs/fapi-2_0-attacker-model-ID2.html) (2022 年 12 月)

NOTE: 「**Baseline プロファイル**」は「**Security プロファイル**」に改名されました。

### FAPI 2.0 Final

- [**FAPI 2.0 Security Profile**](https://openid.net/specs/fapi-security-profile-2_0-final.html) (2025 年 2 月)

- [**FAPI 2.0 Attacker Model**](https://openid.net/specs/fapi-2_0-attacker-model-final.html) (2025 年 2 月)

## 認定プログラム

2025 年 4 月時点で、[OpenID Certification プログラム](https://openid.net/certification/) は、プロバイダーおよびリライングパーティーに向けて、以下の FAPI 2.0 認定プログラムを提供しています。

プロバイダー向け

- [FAPI 2.0 Security Profile Second Implementer’s Draft & Message Signing First Implementer’s Draft](https://openid.net/certification/#FAPI2-SECURITY)
- [Australia FAPI 2.0 ConnectID Implementer’s Draft](https://openid.net/certification/#FAPI2-CONNECTID-AUS)
- [CBUAE FAPI 2.0 Message Signing](https://openid.net/certification/#FAPI2-OP-CBUAE)

リライングパーティー向け

- [FAPI 2.0 Security Profile Second Implementer’s Draft & Message Signing First Implementer’s Draft](https://openid.net/certification/#FAPI2-RP-SECURITY)
- [Australia FAPI 2.0 ConnectID Implementer’s Draft](https://openid.net/certification/#FAPI2-RP-CONNECTID-AUS)
- [CBUAE FAPI 2.0 Message Signing](https://openid.net/certification/#cbuae-fapi-20-message-signing)

## 前提知識

FAPI 2.0 を理解するにあたって、以下の仕様群について目を通しておくことを推奨します。

- [RFC6749](https://www.rfc-editor.org/info/rfc6749) — OAuth 2.0 Authorization Framework
- [RFC6750](https://www.rfc-editor.org/info/rfc6750) — OAuth 2.0 Authorization Framework: Bearer Token Usage
- [RFC7636](https://www.rfc-editor.org/info/rfc7636) — Proof Key for Code Exchange by OAuth Public Clients (PKCE)
- [RFC8705](https://www.rfc-editor.org/info/rfc8705) — OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (MTLS)
- [RFC9449](https://www.rfc-editor.org/info/rfc9449) — OAuth 2.0 Demonstrating Proof of Possession (DPoP)
- [RFC9126](https://www.rfc-editor.org/info/rfc9126) — OAuth 2.0 Pushed Authorization Requests (PAR)
- [RFC8414](https://www.rfc-editor.org/info/rfc8414) — OAuth 2.0 Authorization Server Metadata
- [RFC9207](https://www.rfc-editor.org/info/rfc9207) — OAuth 2.0 Authorization Server Issuer Identification
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)

また、上記仕様群の理解のために以下の記事が参考になります。

- [一番分かりやすい OAuth の説明](https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be)
- [OAuth 2.0 全フローの図解と動画](https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f)
- [一番分かりやすい OpenID Connect の説明](https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe)
- [OpenID Connect 全フロー解説](https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47)
- [IDトークンが分かれば OpenID Connect が分かる](https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06)
- [図解 PAR : OAuth 2.0 Pushed Authorization Requests](https://qiita.com/TakahikoKawasaki/items/97563be46b62a0e02fe6)
- [図解 DPoP (OAuth アクセストークンのセキュリティ向上策の一つ)](https://qiita.com/TakahikoKawasaki/items/34c82fb5c0595b6fc289)

### クライアント認証

FAPI 2.0 Security プロファイルにおいては、以下のクライアント認証方式が利用できます。

#### MTLS を用いたクライアント認証

![スライド7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/453b2e05-3900-416c-b843-034e67e07c87.png)

これは、[RFC8705 のセクション 2](https://www.rfc-editor.org/rfc/rfc8705.html#section-2) に定義される以下の認証方式を指します。

|`tls_client_auth`|
|---|
| この認証方式では、クライアントは TLS ハンドシェイク中に証明書 (X.509 証明書) を提示し、その後認可サーバーはその証明書の検証を行い、**Subject Distinguished Name (DN)** または **Subject Alternative Name (SAN)** の値を用いてクライアントを識別します。これにより認可サーバーは、クライアントが有効な証明書を保持していること、また、正当な秘密鍵を保持していることを確認できます。|

|`self_signed_tls_client_auth`|
|---|
| この認証方式では、クライアントは自己署名による証明書を用いて認証されます。`tls_client_auth` とは異なり、クライアントの証明書チェーンは検証されませんが、クライアントは認可サーバーに対して証明書を登録しておく必要があります。TLS ハンドシェイク中に提示された証明書が登録されたものに合致した場合に限り、クライアント認証は成功します。|

X.509 証明書の詳細については 「[図解 X.509 証明書](https://qiita.com/TakahikoKawasaki/items/4c35ac38c52978805c69)」が参考になります。

#### Private Key Signed JWT を用いたクライアント認証

![スライド8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/baede4c3-eedd-731f-ef28-d4fea23ccb79.png)

これは、[OIDC Core のセクション 9](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication) に定義される以下の認証方式を指します。

|`private_key_jwt`|
|---|
|この認証方式では、クライアントは JSON Web Token (JWT) を生成し、それを秘密鍵で署名します。この JWT は `issuer` や `audience` 等のクレームを含み、クライアントアサーションとして認可サーバーに送信されます。その後認可サーバーは、クライアントの公開鍵を用いて JWT の署名検証を行い、クレーム値の検証処理を行います。|

### アクセストークンの送信者制限メカニズム

FAPI 2.0 Security プロファイルを採用する場合、認可サーバーは MTLS または DPoP ([OAuth 2.0 Demonstrating Proof-of-Possession](https://www.rfc-editor.org/info/rfc9449)) を用いて、アクセストークンの送信者を制限しなければなりません。これはアクセストークンが漏洩した際の不正使用を防止するために必要となります。

#### MTLS を用いたアクセストークン送信者制限

![スライド9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/7cc6a4ff-726e-08de-326f-3f77d2e9444e.png)

[RFC8705 のセクション 3](https://www.rfc-editor.org/rfc/rfc8705.html#section-3) は、MTLS を利用した送信者制限メカニズムを定義しています。概要は以下のようになります。

1. クライアントはトークンエンドポイントに対してアクセストークンを要求する。
2. 認可サーバーは MTLS 通信を確立する過程で、クライアント証明書を取得する。
3. 認可サーバーは、アクセストークン発行時に、クライアント証明書とアクセストークンの紐付けを行う。
4. クライアントはリソースサーバーに対して当該アクセストークンとクライアント証明書を送信する。
5. リソースサーバーは、当該アクセストークンに対して提示されたクライアント証明書が紐づいていることを確認する。

#### DPoP (RFC9449: OAuth 2.0 Demonstrating Proof of Possession)

![スライド10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/c1d443b9-e092-b9c3-c912-cab9074961d5.png)

もう一つのアクセストークン送信者制限メカニズムは、DPoP ([RFC9449: OAuth 2.0 Demonstrating Proof of Possession](https://www.rfc-editor.org/info/rfc9449)) です。概要としては以下のようになります。

1. クライアントは DPoP proof JWT と呼ばれる JWT を生成します。この JWT はクライアントの秘密鍵で署名されていなければなりません。
2. クライアントは DPoP proof JWT を含めてトークンリクエストを送信します。
3. 認可サーバーはクライアントの公開鍵を利用して、受け取った DPoP proof JWT の署名を検証します。
4. 認可サーバーは当該公開鍵の thumbprint を生成したアクセストークンに紐付けます。
5. 認可サーバーはアクセストークンを発行します。
6. クライアントはリソースサーバーにアクセスする前に、先ほどの秘密鍵を使って新たな DPoP proof JWT を生成します。
7. クライアントはアクセストークンとその DPoP proof JWT を含めてリソースサーバーにリクエストを送信します。
8. リソースサーバーは DPoP proof JWT に含まれる公開鍵を利用して、DPoP proof JWT の署名検証を行います。
9. リソースサーバーはアクセストークンが当該公開鍵に紐づいていることを確認します。これにより、「リソースサーバーにアクセスしてきたクライアント」が「アクセストークンを発行したクライアント」であることを確認できます。

DPoP に関する詳細ついては、「[図解 DPoP (OAuth アクセストークンのセキュリティ向上策の一つ)](https://qiita.com/TakahikoKawasaki/items/34c82fb5c0595b6fc289)」が詳しいです。

### 認可コードと DPoP キーの紐付け

![スライド11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/19ed2983-bde2-79ce-52c0-3c38a783deba.png)

RFC9449 は、認可リクエストパラメーターの一つとして `dpop_jkt` を定義しています。本パラメーターを利用することで、認可コードに対してクライアントの公開鍵 (の thumbprint) の紐付けが可能となり、結果として認可コードの所有者証明が可能となります。本メカニズムを利用することで、認可フロー全体を通じた end-to-end のバインディングが可能となります。以下はその概要です。

1. クライアントは公開鍵の thumbprint を計算します。
2. クライアントは thumbprint の値を `dpop_jkt` としてリクエストに含め、認可リクエストを行います。
3. 認可サーバーは `dpop_jkt` の値を認可コードに含めます。
4. 認可サーバーは認可コードを発行します。
5. クライアントは自身の秘密鍵で JWT を署名し、DPoP proof JWT を生成します。
6. クライアントは DPoP proof JWT を含めてトークンリクエストを送信します。
7. 認可サーバーは、DPoP proof JWT に含まれるクライアントの公開鍵を利用し、DPoP proof JWT の検証を行います。
8. 認可サーバーは DPoP proof JWT に含まれる公開鍵の thumbprint が認可コードと紐づいていることを確認します。
9. 認可サーバーは公開鍵の thumbprint を発行されるアクセストークンに紐付けます。
10. 認可サーバーはアクセストークンを発行します。
11. クライアントはリソースサーバーにアクセスする前に、先ほどの秘密鍵を使って新たな DPoP proof JWT を生成します。
12. クライアントはアクセストークンとその DPoP proof JWT を含めてリソースサーバーにリクエストを送信します。
13. リソースサーバーは DPoP proof JWT に含まれる公開鍵を利用して、DPoP proof JWT の署名検証を行います。
14. リソースサーバーはアクセストークンが当該公開鍵に紐づいていることを確認します。これにより、「リソースサーバーにアクセスしてきたクライアント」が「アクセストークンを発行したクライアント」であることを確認できます。

### DPoP Nonce

![スライド12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/892d1b40-a61c-4316-e102-a37bd451c882.png)

DPoP nonce のメカニズムは DPoP proof JWT の有効性を制限するための仕組みです。これにより、漏洩した DPoP proof JWT が攻撃者に使い続けられてしまうリスクを回避できます。概要は以下の通りです。

1. クライアントはサーバーに提供された nonce の値を含めた DPoP proof JWT を生成します。
2. クライアントは DPoP proof JWT を含めてトークンリクエストを送信します。
3. 認可サーバーは DPoP proof JWT の署名検証を行います。
4. 認可サーバーは DPoP proof JWT に含まれる nonce の値がサーバーから提供された値と合致することを確認します。
5. 攻撃者は、何らかの手法でクライアントから DPoP proof JWT を不正に取得します。
6. 攻撃者は取得した DPoP proof JWT を含めて認可サーバーにリクエストを送信します。
7. 認可サーバーは DPoP proof JWT の署名を検証します。
8. 認可サーバーは DPoP proof JWT に含まれる nonce 値の有効性を (有効期限、使用回数等をチェックして) 検証します。もしそれが無効と認められた場合、そのリクエストは拒否されます。

## Security プロファイル

以下のセクションでは、[FAPI 2.0 Security プロファイル (Final)](https://openid.net/specs/fapi-security-profile-2_0-final.html) を詳細に解説していきます。

### 5.1. 概要

#### 5.1.1. はじめに
FAPI 2.0 Security プロファイルは、OAuth 2.0 ([RFC6749](https://www.rfc-editor.org/info/rfc6749)) に基づいたプロファイルであり、[Attacker Model](https://openid.net/specs/fapi-attacker-model-2_0-final.html) に定められるセキュリティ基準を達成し、OAuth Security BCP ([RFC9700](https://www.rfc-editor.org/info/rfc9700)) の推奨に従うことを目的としています。本プロファイルにおける規定事項は、コンフィデンシャルクライアントを前提としており、パブリッククライアントに関しては本ドキュメントの対象外となっています。また、本ドキュメントをもとに認可サーバーやクライアントをスクラッチ実装することは可能ですが、既存の OpenID Connect や OAuth 2.0 の実装を活用して構築することが推奨されています。

#### 5.1.2. 本文書のプロファイリング
本ドキュメントは、形式的な解析により前述の Attacker Model の要件を満たすことが証明された、汎用的かつ高セキュリティな OAuth 2.0 プロファイルです。本ドキュメントおよび関連仕様において、実装者・利用者・エコシステムは、いくつかの選択肢を取ることができます。具体的なユースケースが明確であれば、適切な取捨選択により、セキュリティを向上させ、実装・相互運用性を容易にすることが可能です。ただし、本プロファイルに準拠するためには、必須とされる動作を削除・上書きしてはいけません。そのような変更は、形式的な解析を無効化し、予測不能な形でセキュリティの低下を招く恐れがあるためです。

### 5.2. ネットワークレイヤーの保護

#### 5.2.1. 全エンドポイントに対する要件
ネットワーク攻撃に対抗するために、クライアント、認可サーバー、リソースサーバーは

- TLS 保護されたエンドポイントを提供し、他のサービスへの接続の際には TLS を利用しなければならない。

- TLS 1.2 以降を利用して TLS 接続を確立しなければならない。

- [BCP195](https://www.rfc-editor.org/info/bcp195) の「Secure Use of Transport Layer Security」に規定される推奨事項に従うものとします。

- DV 証明書の不正発行につながり得る DNS スプーフィングを防ぐため、DNSSEC を使用すべきです。

- [RFC9525](https://openid.net/specs/fapi-security-profile-2_0-final.html#RFC9525) に従い、TLS サーバー証明書の検証が必須となります。

- エンドポイントが OV 証明書または EV 証明書のみを使用していても、不正な DV 証明書を使用したエンドポイントによるなりすまし、中間者攻撃 (MITM 攻撃) は可能です。CAAレコード ([RFC8659](https://www.rfc-editor.org/info/rfc8659)) は、これらのリスクを軽減できる有効な手段となります。

#### 5.2.2. Web ブラウザによって利用されないエンドポイントへの要件

TLS 1.2 を利用しており、Web ブラウザによって使用されないエンドポイントについては、以下の要件が課されます。

- TLS 1.2 を使用する場合、サーバーは [BCP195](https://www.rfc-editor.org/info/bcp195) で推奨されている暗号スイートのみを許可しなければなりません。
- TLS 1.2 を使用する場合、クライアントも [BCP195](https://www.rfc-editor.org/info/bcp195) で推奨されている暗号スイートのみを許可することが望ましいです。

##### 5.2.2.1. MTLS エコシステム

一部のエコシステムでは、機密データを転送を必要とする全てのサーバー間エンドポイントにおいて、セキュリティ向上を目的として、トランスポート層で MTLS を実装している場合があります。たとえば、`private_key_jwt` をクライアント認証に使用しつつ、MTLS 通信を組み合わせることができます。相互運用性を容易にするために:

- MTLS を使用するエコシステムは、信頼する認証局 (CA) のリストを返却すべきです。
- 認可サーバーの実装は、[RFC8705](https://openid.net/specs/fapi-security-profile-2_0-final.html#RFC8705) のセクション 5 に記載されている `mtls_endpoint_aliases` メタデータを利用して、MTLS エンドポイントおよび非 MTLS エンドポイントの両者に対応したディスカバリー機構を提供しても構いません。
- クライアントの実装は、`use_mtls_endpoint_aliases` クライアントメタデータ (セクション 5.2.2.1.1 参照) が存在する場合は、それを用いてエンドポイントとの通信を行わなければなりません。

###### 5.2.2.1.1. クライアントメタデータ

Dynamic Client Registration ([RFC7591](https://openid.net/specs/fapi-security-profile-2_0-final.html#RFC7591)) は、OAuth 2.0 クライアントのメタデータを認可サーバーに動的に登録するための API を定義しています。[RFC7591](https://openid.net/specs/fapi-security-profile-2_0-final.html#RFC7591) で定義されたメタデータおよびその拡張は、Dynamic Client Registration を使用しない場合でも認可サーバーの実装にとって有益なクライアントデータモデルを提供します。このような場合、通常、クライアント構成を管理するためのユーザーインターフェースが提供されます。

本仕様では、以下のクライアントメタデータを新たに定義します。

|`use_mtls_endpoint_aliases`|
|---|
|オプショナル。クライアントが、認可サーバーのメタデータにおいて宣言される MTLS エンドポイントエイリアス ([RFC8705](https://openid.net/specs/fapi-security-profile-2_0-final.html#RFC8705)) を、MTLS クライアント認証や証明書バインド型アクセストークンといった用途に限らず、より広範に使用する必要があることを示すフラグです。デフォルト値は `false` です。|

#### 5.2.3. Web ブラウザを使用するエンドポイントの要件

- サーバーは、TLS ストリッピング攻撃への対策を講じなければなりません。この目的のために、プリロード [[preload](https://hstspreload.org/)] された HTTP Strict Transport Security ポリシー ([RFC6797](https://www.rfc-editor.org/info/rfc6797)) を使用することができます。`.bank` や `.insurance` などの一部のトップレベルドメインはこのポリシーを設定しており、それにより配下のすべてのセカンドレベルドメインが保護されます。

- TLS 1.2 を使用する場合、サーバーは [BCP195](https://www.rfc-editor.org/info/bcp195) で許可されている暗号スイートのみを使用しなければなりません。

- サーバーは、認可エンドポイントにおいて [CORS.Protocol](https://fetch.spec.whatwg.org/#http-cors-protocol) による CORS をサポートしてはなりません。クライアントは当該エンドポイントに対して直接アクセスをするのではなく、リダイレクトを実行する必要があるためです。

NOTE 1: TLS 1.2 を使用する場合、Web ブラウザによって使用されるエンドポイントでは [BCP195](https://www.rfc-editor.org/info/bcp195) において許可されている任意の暗号スイートを使用できます。一方、Webブラウザによって使用されないエンドポイントでは、[BCP195](https://www.rfc-editor.org/info/bcp195) で推奨されている暗号スイートのみが使用可能です。

NOTE 2: [BCP195](https://www.rfc-editor.org/info/bcp195) の新しいバージョンは、IETF によって定期的に公開される予定です。実装者は、新しいバージョンが公開された場合、遅くとも 12 か月以内にそれに準拠することが求められます。

### 5.3. プロファイル

#### 5.3.1. 全般的要件

以下は、本プロファイルの関連仕様群です。

- [OAuth 2.0 Authorization Framework (RFC6749)](https://www.rfc-editor.org/info/rfc6749)
- [OAuth 2.0 Bearer Tokens (RFC6750)](https://www.rfc-editor.org/info/rfc6750)
- [Proof Key for Code Exchange by OAuth Public Clients (RFC7636)](https://www.rfc-editor.org/info/rfc7636)
- [OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (RFC8705)](https://www.rfc-editor.org/info/rfc8705)
- [OAuth 2.0 Demonstrating Proof of Possession (RFC9449)](https://www.rfc-editor.org/info/rfc9449)
- [OAuth 2.0 Pushed Authorization Requests (RFC9126)](https://www.rfc-editor.org/info/rfc9126)
- [OAuth 2.0 Authorization Server Metadata (RFC8414)](https://www.rfc-editor.org/info/rfc8414)
- [OAuth 2.0 Authorization Server Issuer Identification (RFC9207)](https://www.rfc-editor.org/info/rfc9207)
- [OpenID Connect Core 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-core-1_0.html)

#### 5.3.2. 認可サーバーの要件

##### 5.3.2.1. 全般的要件

|1. shall distribute discovery metadata (such as the authorization endpoint) via the metadata document as specified in [OIDD] and [RFC8414]; |
|---|
|1. [OIDD] および RFC8414 で指定されているように、サーバーメタデータ (認可エンドポイントの情報等) を公開しなければなりません。|

認可サーバーは [OpenID Connect Discovery 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html) と [RFC8414](https://www.rfc-editor.org/info/rfc8414) に従い、well-known URI (e.g. `https://as.example.com/.well-known/openid-configuration`) を通じてサーバーメタデータを公開する必要があります。

以下のサーバーメタデータの一例です。

```json
{
  "issuer": "https://as.example.com",
  "authorization_endpoint": "https://as.example.com/authz",
  "token_endpoint": "https://as.example.com/token",
  "token_endpoint_auth_methods_supported": ["client_secret_basic", "private_key_jwt"],
  ...
}
```

|2. shall reject requests using the resource owner password credentials grant;|
|---|
|2. リソースオーナーパスワードクレデンシャルグラントを使用しているリクエストは拒否しなければなりません。|

本プロファイルでは、リソースパスワードクレデンシャルグラントの使用は禁止されます。一方で、以下のようなグラントタイプの使用は禁止されておりません。

- `authorization_code`
- `refresh_token`
- `client_credentials`
- `urn:openid:params:grant-type:ciba`

|3. shall only support confidential clients as defined in [RFC6749];|
|---|
|3. [RFC6749] に規定されるコンフィデンシャルクライアントのみをサポートしなければなりません。|

認可サーバーは [RFC6749](https://www.rfc-editor.org/rfc/rfc6749.html) に規定されるコンフィデンシャルクライアントのみをサポートしなければなりません。

|4. shall only issue sender-constrained access tokens;<br>5. shall use one of the following methods for sender-constrained access tokens:<br>&nbsp;&nbsp;• MTLS as described in [RFC8705],<br>&nbsp;&nbsp;• DPoP as described in [RFC9449];|
|---|
|4. 送信者制限されたアクセストークンのみを発行しなければならない、<br>5. 送信者制限のメカニズムとして、以下のいずれかを利用しなければならない:<br>&nbsp;&nbsp;• [RFC8705] に定義される MTLS<br>&nbsp;&nbsp;• [RFC9449] に定義される DPoP|

認可サーバーは、漏洩したアクセストークンの悪用を防止するため、アクセストークンの送信者制限メカニズムとして MTLS ([RFC8705](https://www.rfc-editor.org/info/rfc8705)) または DPoP ([RFC9449](https://datatracker.ietf.org/doc/html/rfc9449)) を利用しなければなりません。

|6. shall authenticate clients using one of the following methods:<br>&nbsp;&nbsp;• MTLS as specified in Section 2 of [RFC8705], or<br>&nbsp;&nbsp;• `private_key_jwt` as specified in Section 9 of [OIDC];|
|---|
|6. クライアント認証は以下のいずれかを利用しなければなりません:<br>&nbsp;&nbsp;• [RFC8705] のセクション 2 に規定される MTLS<br>&nbsp;&nbsp;• [OIDC] のセクション 9 に規定される private_key_jwt|

具体的には、以下のクライアント認証方式が許容されます。

- `tls_client_auth` ([RFC8705 の セクション 2.1](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.1))
- `self_signed_tls_client_auth` ([RFC8705 の セクション 2.2](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.2))
- `private_key_jwt` ([OIDC Core の セクション 9](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication))

以下のテーブルは、FAPI 1.0 と FAPI 2.0 のクライアント認証方式における違いをまとめたものです。

![client_auth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/28224826-bd68-a53a-6be5-82cf2c6d3d82.png)

詳細は、[クライアント認証](#クライアント認証)のセクションを参照してください。

| 7. shall not expose open redirectors (see Section 4.11 of [I-D.ietf-oauth-security-topics]); |
|---|
| 7. オープンリダイレクトを許容してはなりません。 ([I-D.ietf-oauth-security-topics] のセクション 4.10 を参照してください) |

本要件は、「[OAuth 2.0 Security Best Current Practice のセクション 4.10](https://www.ietf.org/archive/id/draft-ietf-oauth-security-topics-21.html#section-4.10)」を参照しています。すなわち、認可サーバーとクライアントはオープンリダイレクトを許容してはならないということです。オープンリダイレクトとは、悪意のあるユーザーが正当なウェブサイトを使用して、あるユーザーを別の危険なサイトに誘導する攻撃方法です。この攻撃手段はフィッシング攻撃の手法としてよく利用される方法です。

|8. shall only accept its issuer identifier value (as defined in [RFC8414]) as a string in the aud claim received in client authentication assertions;|
|---|
|8. クライアントアサーションの `aud` クレームに含まれる値は、文字列型かつ認可サーバー自身の発行者識別子 ([RFC8414] にて規定) の値でなければなりません。|

認可サーバーが `private_key_jwt` によりクライアント認証する場合、認可サーバーはクライアントアサーションに含まれる `aud` クレームとして、自身の発行者識別子 (`issuer`) の値を受け入れる必要があります。この場合、クライアントアサーションに含まれる `aud` クレームの値は、認可サーバーの発行者識別子と一致する文字列 (例: `"https://as.example.com"`) でなければなりません。(注意：発行者識別子を含む文字列型配列 (例: `["https://as.example.com"]`) は許容されません。)

```
✅ aud = "https://as.example.com"
```

```
❌ aud = ["https://as.example.com"]
```

|9. shall not use refresh token rotation except in extraordinary circumstances (see Note 1 below);|
|---|
|9. 例外的な状況を除いて、リフレッシュトークンのローテーションは使用してはなりません。(NOTE 1 を参照してださい)|

認可サーバーは、例外的な状況を除いて、リフレッシュトークンのローテーション (アクセストークンのリフレッシュの度に新しいリフレッシュトークンが発行される仕組み) を禁止しなければなりません。詳細は、注則 1 を参照してください。

|10. if using DPoP, may use the server provided nonce mechanism (as defined in Section 8 of [RFC9449]);|
|---|
|10. DPoPを使用する場合、サーバー提供の nonce (RFC9449 のセクション 8 にて定義) を使用することができる。|

DPoP が送信者制約アクセストークンメカニズムとして使用される場合、認可サーバーは [DPoP nonce メカニズム](#dpop-nonce)を採用して、リプレイアタック (攻撃者が有効な DPoP proof を盗み、それを再利用して認可を得る攻撃) 等の攻撃を防ぐことができます。

|11. shall issue authorization codes with a maximum lifetime of 60 seconds;|
|---|
|11. 認可コードの有効期限は 60 秒以下にしなければならない。|

認可コードの有効期限は 60 秒を超えてはなりません。

|12. if using DPoP, shall support "Authorization Code Binding to DPoP Key" (as required by Section 10.1 of [RFC9449]);|
|---|
|12. DPoPを使用する場合、「認可コードと DPoP キーの紐付け」をサポートしなければなりません。(RFC9449 のセクション 10 によって要求)|

認可サーバーがアクセストークンの送信者制約メカニズムとして DPoP をサポートする場合、[認可コードと DPoP キーの紐付け](#認可コードと-dpop-キーの紐付け) をサポートする必要があります。このメカニズムにより、クライアントは認可コードの所有者証明が可能となり、認可プロセス全体を通じて end-to-end のバインディングを実現することができます。

:::note warn
注意: ただし、これはクライアントが「認可コードと DPoP キーの紐付け」を使用しなければならないという意味ではないです。
:::

|13. to accommodate clock offsets, shall accept JWTs with an iat or nbf timestamp between 0 and 10 seconds in the future but shall reject JWTs with an iat or nbf timestamp greater than 60 seconds in the future. See Note 3 for further details and rationale;|
|---|
|13. 時刻のずれに対応するために、JWT に含まれる iat または nbf の値が現在時刻より 0〜10 秒先の値であっても、その JWT を受け入れなければなりません。ただし、現在時刻より 60 秒を超える値が設定されている場合は、その JWT を拒否しなければなりません。詳細およびその理由については NOTE 3 を参照してください。|

時刻のずれ (クロックスキュー問題) に対応するために、認可サーバーは `iat` クレームや `nbf` クレームの値が 0~10 秒先の値であってもその JWT を受理しなければなりません。しかし、「**iat または nbf の値 > 現在時刻 + 60 秒**」の場合は、その JWT をリジェクトしなければなりません。

|14. should restrict the privileges associated with an access token to the minimum required for the particular application or use case.|
|---|
|14. アクセストークンに付与する権限は、特定のアプリケーションやユースケースにおける必要最小限の権限に留めるべきです。|

記述の通り、アクセストークンに対する不要な権限付与は避けるべきです。

|NOTE 1: The use of refresh token rotation does not provide security benefits when used with confidential clients and sender-constrained access tokens. This specification prohibits the use of refresh token rotation for security reasons as it causes user experience degradation and operational issues whenever the client fails to store or receive the new refresh token and has no option to retry.<br/><br/>However, as refresh token rotation may be required from time to time for infrastructure migration or similar extraordinary circumstances, this specification allows it, provided that authorization servers offer clients the time-limited option to retry with the old refresh token in case of failure. Implementers need to consider a secure mechanism for clients to recover from a loss of a new refresh token on issue. The details of this mechanism are outside the scope of this specification.|
|---|
|NOTE 1: コンフィデンシャルクライアントと送信者制限されたアクセストークンが併用される場合、リフレッシュトークンのローテーションはセキュリティ上のメリットをもたらしません。本仕様ではリフレッシュトークンのローテーションをセキュリティ上の理由から禁止します。というのも、クライアントが新規リフレッシュトークンの保存・受理に失敗し、リトライする方法がない場合、UX の悪化と運用上の問題が引き起こされてしまうからです。<br/><br/>とはいえ、リフレッシュトークンのローテーションはインフラの移行時や同様の例外的状況などにおいて時折必要になるケースがあります。そのため、クライアントが新規リフレッシュトークンの保存・受理に失敗した際に古いリフレッシュトークンを用いて一定期間内にリトライできる仕組みを認可サーバーが提供する場合は、リフレッシュトークンのローテーションを許容しても差し支えありません。実装者は、クライアントが新しいリフレッシュトークンを失ってしまった状態から安全にリカバリーする仕組みついて検討する必要があります。そのような仕組みの詳細については本仕様の対象外とします。|

リフレッシュトークンのローテーションは例外的な状況を除き禁止されます。もしリフレッシュトークンのローテーションを実装する場合は、以下のように古いリフレッシュトークンによるリフレッシュを時間制限付きで可能とするメカニズムを用意する必要があります。

![スライド13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/a14b8b0d-d757-412c-9297-3a9202ca17d3.png)

|NOTE 2: This document is structured to support a variety of grants to be used with the general requirements above. For example the client credentials grant or the CIBA grant [CIBA]. Implementers should note that as of the time of writing only the authorization code flow and CIBA flows have been through a detailed security analysis [FAPI2SEC].|
|---|
|NOTE 2: 本仕様は、様々なグラントを上記全般的要件と組みあせて利用できるように設計されています。例えば、クライアントクレデンシャルグラント、CIBA (Client Initiated Backchannel Authentication) グラントなどです。実装者は、現時点でセキュリティ分析が完了しているのは、認可コードフローと CIBA フローのみであることに留意するべきです。|

認可サーバーは、項目 2 で禁止されたグラントに含まれないグラント (CIBA グラントなど) をサポートすることができます。

|NOTE 3: Clock skew is a cause of many interoperability issues. Even a few hundred milliseconds of clock skew can cause JWTs to be rejected for being "issued in the future". The DPoP specification [RFC9449] suggests that JWTs are accepted in the reasonably near future (on the order of seconds or minutes). This document goes further by requiring authorization servers to accept JWTs that have timestamps up to 10 seconds in the future. 10 seconds was chosen as a value that does not affect security while greatly increasing interoperability. Implementers are free to accept JWTs with a timestamp of up to 60 seconds in the future. Some ecosystems have found that the value of 30 seconds is needed to fully eliminate clock skew issues. To prevent implementations switching off iat and nbf checks completely this document imposes a maximum timestamp in the future of 60 seconds.|
|---|
|NOTE 3: クロックスキュー (時刻のずれ) は相互運用性に関わる様々な問題を引き起こす原因となります。数百ミリ秒のクロックスキューですら、JWT が「将来に発行されたものである」と見なされリジェクトされる原因となります。DPoP の仕様 [RFC9449] によれば、JWT が将来のタイムスタンプを持っていても、それが秒や分の単位であれば、その JWT は受理されることが推奨されます。本仕様ではさらに踏み込んで、認可サーバーは最大 10 秒先のタイムスタンプを持つ JWT を受理しなければならないとしています。10 秒という値は、セキュリティを損なわず、かつ、相互運用性を大きく向上させる値として選定されています。実装者は、最大 60 秒先のタイムスタンプを持つ JWT を受理することも可能です。いくつかのエコシステムでは、クロックスキュー問題を解決するために 30 秒という値が必要であることも分かっています。実装上 iat と nbf の検証が完全に無効になってしまうのを防ぐために、本仕様ではタイムスタンプの上限を 60 秒先までと定めています。|

項目 13 でも述べたように、JWT 内の `iat` と `nbf` の最大値は「現在時刻 + 60 秒」です。それよりも大きな値が設定されている場合は、その JWT はリジェクトされなければなりません。

##### 5.3.3.2. 認可エンドポイントを使うフローの要件

|1. shall require the value of response_type described in [RFC6749] to be code;|
|---|
|1. [RFC6749] で詳述されている `response_type` の値として、`code` を要求しなければなりません。|

認可サーバーは `response_type=code` を要求しなければなりません。他のレスポンスタイプは許容されません。

|2. shall support client-authenticated pushed authorization requests according to [RFC9126];|
|---|
|2. [RFC9126] に従って、クライアント認証されるプッシュ型認可リクエストをサポートしなければなりません。|

認可サーバーは「[RFC9126, OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/info/rfc9126)」(PAR) をサポートし、プッシュ型認可リクエストエンドポイントで、[指定されたクライアント認証方式](#クライアント認証)を用いてクライアント認証を行う必要があります。

PAR についての詳細は、「[図解 PAR : OAuth 2.0 Pushed Authorization Requests](https://qiita.com/TakahikoKawasaki/items/97563be46b62a0e02fe6)」が参考になります。

|3. shall reject authorization requests sent without [RFC9126];|
|---|
|3. [RFC9126] を使用せずに送信された認可リクエストを拒否しなければなりません。|

認可サーバーは PAR を使用せずに送信された認可リクエストは拒否しなければなりません。

|4. shall reject pushed authorization requests without client authentication;|
|---|
|4. クライアント認証なしのプッシュ型認可リクエストは拒否しなければなりません。|

項目 2 で述べたように、認可サーバーは PAR エンドポイントにおいて、項目 6 にリストされたクライアント認証方法のいずれかを使用してクライアントを認証しなければなりません。

|5. shall require PKCE [RFC7636] with `S256` as the code challenge method;|
|---|
|5. PKCE [RFC7636] の使用を要求し、コードチャレンジメソッドの値は `S256` でなければなりません。|

認可サーバーは [RFC7636, PKCE (Proof Key for Code Exchange)](https://www.rfc-editor.org/info/rfc7636) を使用を必須とし、`code_challenge_method` パラメータの値として `S256` を要求しなければなりません。

|6. shall require the redirect_uri parameter in pushed authorization requests;|
|---|
|6. プッシュ型認可リクエスト内に `redirect_uri` パラメーターが含まれることを要求しなければなりません。|

認可サーバーは、PAR リクエストに `redirect_uri` パラメーターが含まれることを要求しなければなりません。

|7. shall return an iss parameter in the authorization response according to [RFC9207];|
|---|
|7. [RFC9207](https://www.rfc-editor.org/info/rfc9207) に従って、認可レスポンスに `iss` パラメータを含めなければなりません。|

認可サーバーは [RFC9207](https://www.rfc-editor.org/info/rfc9207) に従い、認可レスポンスに `iss` パラメータを含めなければなりません。これは mix-up アタックを防ぐのに有効です。

NOTE: `iss` の値は、クエリやフラグメント成分を含まない「https」で始まる URL でなければならない 。(例: https://as.example.com)

|8. shall not transmit authorization responses over unencrypted network connections, and, to this end, shall not allow redirect URIs that use the "http" scheme except for native clients that use loopback interface Redirection as described in Section 7.3 of [RFC8252];|
|---|
|8. 暗号化されていないネットワーク接続を介して認可レスポンスを送信しないこと、及びこの目的で http スキームを使用するリダイレクト URI を許可してはなりません。ただし [RFC8252] セクション 7.3 に記述されたループバックインターフェースリダイレクションを使用するネイティブクライアントについてはこの限りではありません。|

リダイレクト URI が http スキームを使用する場合、クライアントはネイティブクライアントでなければならず、リダイレクト URI はループバックリダイレクト URI でなければなりません。ループバックリダイレクト URI は [RFC8252 の セクション7.3](https://www.rfc-editor.org/rfc/rfc8252.html#section-7.3) において以下のように定義されています。

![host_type.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/c989288e-6e09-6436-e7dd-ea032c9cc5eb.png)

注意: ループバックリダイレクト URI の要件として、「リクエスト時に任意のポートを指定できる」というものがあります。これは、クライアントによってはリクエスト時にオペレーティングシステムから利用可能なエフェメラルポートを取得する場合があり、そのようなクライアントを許容するためです。

詳細については、「[ループバックインターフェースリダイレクション](https://qiita.com/TakahikoKawasaki/items/007bf5b722f0a7c6bdd9)」を参照してください。

|9. shall reject an authorization code (Section 1.3.1 of [RFC6749]) if it has been previously used;|
|---|
|9. 以前に使用された認可コード ([RFC6749](https://www.rfc-editor.org/info/rfc6749) のセクション 1.3.1) を拒否しなければなりません。|

認可コードが以前に使用されたことを検出した場合、認可サーバーはそのリクエストを拒否しなければなりません。

|10. shall not use the HTTP 307 status code when redirecting a request that contains user credentials to avoid forwarding the credentials to a third party accidentally (see Section 4.12 of [I-D.ietf-oauth-security-topics]);|
|---|
|10. ユーザーの認証情報を含むリクエストをリダイレクトする際に HTTP 307 ステータスコードを使用してはなりません。([I-D.ietf-oauth-security-topics] のセクション 4.11 を参照)|

HTTP 307 を使用すると、オリジナルの POST リクエストが新しい場所 (URI) に再度 POST 送信 (リダイレクト) されるため、リダイレクト先が信頼できない場合には機密データが意図しない第三者に漏洩してしまう可能性があります。例えば、ユーザーが https://example.com/login にログインフォームを提出し、サーバーが https://otherdomain.com/process に 307 リダイレクトを返した場合、ブラウザは元のログインリクエストを新しい URL に再送し、そのリクエストにはユーザーの認証情報 (ID、パスワード等) が含まれます。もし otherdomain.com にクレデンシャル情報を渡すことが想定外である場合や、otherdomain.com の安全性が低い場合には、これは問題となり得ます。

|11. should use the HTTP 303 status code when redirecting the user agent using status codes;|
|---|
|11. ユーザーエージェントをリダイレクトする際には HTTP 303 ステータスコードを使用すべきです。|

HTTP 303 ステータスコードは特に POST または PUT リクエストの後に使用され、クライアントはリダイレクト先に GET リクエストでアクセスすることになります。これにより、ユーザーがページを更新した場合に、オリジナルの POST または PUT リクエストが再送されるのを防げます。例えば、https://example.com/submit にフォームを提出した後、サーバーが 303 ステータスコードと https://example.com/thank-you を指す Location ヘッダーで応答すると、クライアントのブラウザは自動的に thank-you ページへの GET リクエストを発行します。これによって、ページの更新によるフォームデータの再送を防止することができます。

|12. shall issue pushed authorization requests `request_uri` with `expires_in` values of less than 600 seconds;|
|---|
|12. プッシュ型認可リクエストに対して発行される `request_uri` は `expires_in` の値が 600 秒未満でなければなりません。|

PAR エンドポイントによって発行されるリクエスト URI は、有効期限が 600 秒未満でなければなりません。これによりリプレイアタック等のセキュリティリスクを軽減することができます。

|13. should provide end-users with all necessary information to make an informed decision about whether to consent to the authorization request, including the identity of the client and the scope of the authorization;|
|---|
|13. エンドユーザーがその認可リクエストに同意するのかどうかを適切に判断できるよう、クライアントの識別情報や認可のスコープを含め、必要な情報を提供すべきです。|

文言の通りです。

|14. if supporting [OIDC], shall support nonce parameter values up to 64 characters in length, may reject nonce values longer than 64 characters.|
|---|
|14. [OIDC] をサポートする場合、64 文字までの nonce パラメーターをサポートしなければなりません。また、64 文字よりも長い nonce はリジェクトしてもよいです。|

先の述べたように、nonce はリプレイアタックの対策として有効です。本プロファイルでは 64 文字までの nonce はサポートしなければなりません。64 文字以上の nonce をリジェクトするかどうかについては、認可サーバーの実装次第ということになります。

|NOTE 1: If replay identification of the authorization code is not possible, it is desirable to set the validity period of the authorization code to one minute or a suitable short period of time. The validity period may act as a cache control indicator of when to clear the authorization code cache if one is used.|
|---|
|NOTE 1: 認可コードの再利用の検知が難しい場合、認可コードの有効期間を 1 分または適切な短い期間に設定することが望ましいです。この有効期間は、「いつ認可コードのキャッシュをクリアすべきか」を示すキャッシュコントロール指標として活用できます。|

認可コードのリプレイアタックを防止できない場合、その有効期間を 1 分またはその他の短い期間に限定することが推奨されます。この値は、「使用中のキャッシュからいつ認可コードを削除すべきか」を示す指標として利用できます。

|NOTE 2: The `request_uri` `expires_in` time must be sufficient for the user's device to receive the link and the user to complete the process of opening the link. In many cases (poor network connection or where the user has to manually select the browser to be used) this can easily take over 30 seconds.|
|---|
|NOTE 2: `request_uri` の `expires_in` の値は、ユーザーのデバイスがリンクを受信し、リンクを開くまでのプロセスを完了するのに十分な長さでなければなりません。大抵の場合 (ネットワーク接続が悪い、またはユーザーが使用するブラウザーを手動で選択する必要があるなどの理由で)、これには 30 秒以上かかることがよくあります。|

リクエスト URI の有効期限は、遅いネットワーク接続やユーザーが手動でブラウザを選択する必要があるなど、潜在的な遅延を考慮して十分な長さでなければなりません。これにより、そのような遅延が 30 秒を超えるケースも補うことができます。

|NOTE 3: It is recommended that authorization servers that enforce one-time use of `request_uri` values ensure the enforcement takes place at the point of authorization, not at the point of loading an authorization page. This prevents user software that preloads urls from invalidating the `request_uri`.|
|---|
|NOTE 3: 認可サーバーの制約により `request_uri` が一度しか使用できない場合、その制約は、認可ページの読み込み時ではなく、認可の実行時点で適用することが推奨されます。これは、ユーザー側のソフトウェアが URL を事前に読み込むことによって `request_uri` を無効化してしまうのを防ぐためです。|

[RFC9126](https://datatracker.ietf.org/doc/html/rfc9126) にあるように、一度使用されたリクエスト URI は無効化されるべきです。ではどの段階でその無効化を行うべきなのかというと、結論としては **「ユーザーが認可を実行したタイミング」** となります。他に考えられるのは「認可ページをロードしたタイミング」ですが、この場合、ユーザー側のソフトウェア (ブラウザ等) が認可ページを事前ローディングしたタイミングでそのリクエスト URI が無効化されてしまい、本ローディング際にエラーとなってしまいます。

|NOTE 4: In this document the `state` parameter is not used for CSRF protection, but may be used to by the client for application state. In circumstances where clients encode application state in a JWT the length of the `state` parameter value could be in excess of 1000 characters.|
|---|
|NOTE 4: 本仕様では、`state` パラメーターは CSRF アタックの対策のためには使用されませんが、クライアントがアプリケーションの状態管理のために使用することがあります。クライアントがアプリケーションの状態を 暗号化して JWT 内に埋め込む場合、`state` パラメーターの長さは優に 1000 文字を超える場合があり得ます。|

本仕様では、CSRF アタックへの対策として `state` パラメーターを要求しません。本仕様では [PKCE (RFC7636)](https://www.rfc-editor.org/info/rfc7636) が必須となっているため、副次的に CSRF アタックを防ぐことができてしまうからです。

|NOTE 5: The use of OAuth 2.0 Rich Authorization Requests (RAR) [RFC9396] is recommended when the scope parameter is not expressive enough to convey the authorization that a client may want to obtain.|
|---|
|NOTE 5: クライアントが要求する認可内容を `scope` パラメーターを使って十分に表現できない場合、OAuth 2.0 Rich Authorization Requests (RAR) [RFC9396] の使用が推奨されます。|

「銀行口座 1234 に対して最大で $500 の支払いのためにアクセスしたい」といった内容の認可要求を、`payments` といったスコープのみで表現するのは容易ではありません。そのような場合、[RAR (RFC9396)](https://datatracker.ietf.org/doc/rfc9396/) に規定される `authorization_details` を利用すれば、以下のように以下のように表現できます。

```
"authorization_details": [
  {
    "type": "payment_initiation",
    "debtorAccount": {
      "accountNumber": "1234"
    },
    "instructedAmount": {
      "currency": "USD",
      "amount": "500.00"
    },
    "creditorName": "Merchant A",
    "creditorAccount": {
      "iban": "DE02100100109307118603"
    }
  }
]
```

### 5.3.3. クライアントの要件

#### 5.3.3.1. 全般的要件

|1. shall support sender-constrained access tokens using one or both of the following methods:<br>&nbsp;&nbsp;•MTLS as described in [RFC8705],<br>&nbsp;&nbsp;•DPoP as described in [RFC9449];|
|---|
|1. 以下の方法のいずれかを使用して送信者制限されたアクセストークンをサポートしなければなりません:<br>&nbsp;&nbsp;•[RFC8705] の MTLS<br>&nbsp;&nbsp;•[I-D.ietf-oauth-dpop] の説明されている DPoP|

この要求についての詳細は、[認可サーバーの全般的要件](#5321-全般的要件)の項目 5 を参照ください。以下は DPoP を使用したトークンリクエストの例です。`DPoP` リクエストヘッダーには DPoP proof JWT が含まれています。

```bash
POST /token HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
DPoP: eyJ0eXAiOiJkc...

grant_type=authorization_code\&client_id={CLIENT_ID}\&code={AUTHORIZATION_CODE}\&redirect_uri={REDIRECT_URI}\...
```

|2. shall support client authentication using one or both of the following methods:<br>&nbsp;&nbsp;•MTLS as specified in Section 2 of [RFC8705],<br>&nbsp;&nbsp;•private_key_jwt as specified in Section 9 of [OIDC];|
|---|
|2. 以下の方法のいずれかを使用してクライアント認証をサポートしなければならない:<br>&nbsp;&nbsp;•[RFC8705] のセクション 2 で指定された MTLS<br>&nbsp;&nbsp;•[OIDC] のセクション 9 で指定された private_key_jwt|

具体的には、クライアントは以下の認証方法をサポートする必要があります。

- `tls_client_auth` ([RFC8705 の セクション 2.1](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.1))

- `self_signed_tls_client_auth` ([RFC8705 の セクション 2.2](https://www.rfc-editor.org/rfc/rfc8705.html#section-2.%EF%BC%92))

- `private_key_jwt` ([OIDC Core の セクション 9](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication))

|3. shall send access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750] or Section 7.1 of DPoP [RFC9449];|
|---|
|3. [RFC6750] のセクション 2.1 か [RFC9449] のセクション 7.1 に記載されている通り、HTTP ヘッダーにアクセストークンを含めて送信しなければならない。|

Bearer トークンと DPoP トークンの送信例は以下の通りです。

```:Bearer トークン
Authorization: Bearer {Access Token}
```

```:DPoP トークン
Authorization: DPoP {Access Token}
DPoP: {DPoP Proof JWT}
```

|4. shall not expose open redirectors (see Section 4.11 of [I-D.ietf-oauth-security-topics]);|
|---|
|4. オープンリダイレクトを許可しない ([I-D.ietf-oauth-security-topics] のセクション 4.10 参照)|

[認可サーバーの全般的要件](#5321-全般的要件)の項目 7 を参照してください。

|5. if using `private_key_jwt`, shall use the authorization server's issuer identifier value (as defined in [RFC8414]) in the `aud` claim in client authentication assertions. The issuer identifier value shall be sent as a string not as an item in an array.|
|---|
|5. `private_key_jwt` を使用する場合、認可サーバーの発行者識別子の値 ([RFC8414](https://www.rfc-editor.org/info/rfc8414) で定義) をクライアントアサーションの `aud` クレームに使用しなければならない。発行者識別子の値は文字列として送るべきで、配列内の要素であってはならない。|

クライアントが `private_key_jwt` によってクライアント認証を行う場合、クライアントアサーションの `aud` クレームの値は、認可サーバーの発行者識別子 (`issuer`) を文字列 (例: `https://as.example.com`) として設定しなければなりません。**これは文字列配列内の要素であってはなりません。**

|6. shall support refresh tokens and their rotation;|
|---|
|6. リフレッシュトークン及びそのローテーションをサポートしなければならない。|

クライアントはリフレッシュトークンフロー (RFC6749) とそのローテーションをサポートしなければなりません。リフレッシュトークンローテーションの詳細については、[認可サーバーの全般的要件](#5321-全般的要件)の項目 9 を参照ください。

|7. if using MTLS client authentication or MTLS sender-constrained access tokens, shall support the mtls_endpoint_aliases metadata defined in [RFC8705];|
|---|
|7. MTLS クライアント認証または MTLS によって送信者制限されたアクセストークンを使用する場合、[RFC8705](https://www.rfc-editor.org/info/rfc8705) で定義された `mtls_endpoint_aliases` メタデータをサポートしなければならない。|

MTLS クライアント認証または MTLS によって送信者制限されたアクセストークンを使用する場合、クライアントはサーバーメタデータに定義されたエンドポイントエイリアス (`mtls_endpoint_aliases` メタデータ) をサポートしなければなりません。これはサーバーの well-known URL 内に定義されています。

|8. if using DPoP, shall support the server provided nonce mechanism (as defined in Section 8 of [RFC9449]);|
|---|
|8. DPoP を使用する場合、[I-D.ietf-oauth-dpop] のセクション 8 で定義される「サーバーによって提供される nonce」のメカニズムをサポートしなければなりません。|

クライアントがアクセストークンの送信者制約メカニズムとして DPoP を使用する場合、[DPoP nonce](#dpop-nonce) のメカニズムをサポートしなければなりません。

|9. shall only use authorization server metadata (such as the authorization endpoint) retrieved from the metadata document as specified in [OIDD] and [RFC8414];|
|---|
|9. 認可サーバーのメタデータ (例えば認可エンドポイント) については、[OIDD] および [RFC8414] で規定されるメタデータドキュメントから取得したもののみを使用しなければなりません。|

クライアントが利用できる認可サーバーのメタデータは、認可サーバーの well-known URI (e.g. `https://as.example.com/.well-known/openid-configuration`) から見つかるメタデータに限定されます。well-known URI は、サーバーメタデータを [OpenID Connect Discovery 1.0 errata set 1](https://openid.net/specs/openid-connect-discovery-1_0.html) および [RFC8414](https://www.rfc-editor.org/info/rfc8414) で規定された通りに公開するものです。

|10. shall ensure that the issuer URL used as the basis for retrieving the authorization server metadata is obtained from an authoritative source and using a secure channel, such that it cannot be modified by an attacker;|
|---|
|10. 認可サーバーのメタデータを取得するためのベースとして使用される発行者 URL は、攻撃者による改竄を防止するため、信頼できる情報源から安全なチャネルを通じて取得されなければなりません。|

認可サーバーの発行者 URL (例: `https://as.example.com`) は、正当な URL でなければならず、かつその情報源は信頼性があるものでなければなりません。また、発行者 URL は HTTPS のような安全なチャネルを通じて取得されなければなりません。

|11. shall ensure that this issuer URL and the issuer value in the obtained metadata match;|
|---|
|11. この発行者 URL と取得したメタデータ内の `issuer` 値が一致することを確認しなければなりません。|

クライアントは、認可サーバーのメタデータに規定される `issuer` 値と、認可サーバーの発行者 URL が一致することを確認しなければなりません。

|12. shall initiate an authorization process only with the end-user's explicit or implicit consent and protect initiation of an authorization process against cross-site request forgery, thereby enabling the end-user to be aware of the context in which a flow was started;|
|---|
|12. 認可プロセスの開始は、エンドユーザーの明示的または暗黙的な同意を得た場合に限り、CSRF (クロスサイトリクエストフォージェリ) 対策を講じた上で実施しなければなりません。また、それにより、エンドユーザーがどのような文脈でそのフローが開始されたのかを認識できるようにしなければなりません。|

|13. should request authorization with the least privileges necessary for the specific application or use case.|
|---|
|13. 特定のアプリケーションやユースケースにとって必要最小限の権限で認可をリクエストすべきです。|

この二つの要件については文言の通りです。

|NOTE 1: This profile may be used by confidential clients on a user-controlled device where the system clock may not be accurate, causing `private_key_jwt` client authentication to fail. In such circumstances a client should consider using the HTTP date header returned from the server to synchronize its own clock when generating client assertions.|
|---|
|NOTE 1: システム時刻が正確ではない可能性があるユーザー制御下のデバイス上で、コンフィデンシャルクライアントが本プロファイルを使用する場合、`private_key_jwt` によるクライアント認証は失敗する可能性があります。そのような場合、クライアントはアサーションの生成時にサーバーから返却された HTTP Date ヘッダーの値を使用して自身の時刻を同期させることを考慮すべきです。|

コンフィデンシャルクライアントの中には、ユーザー制御下のデバイス上に存在するものもあります。そのようなクライアントの場合、システム時刻の不正確さが原因となり `private_key_jwt` を用いたクライアント認証が失敗する可能性があります。この場合、クライアントはサーバーから返却される HTTP `Date` ヘッダーを参照して、自身の時刻を同期することが推奨されます。これはクライアントアサーションの `exp` クレーム等の値を生成する際などに重要となってきます。

|NOTE 2: Although authorization servers are required to support "Authorization Code Binding to DPoP Key" (as defined by Section 10.1 of [RFC9449]), clients are not required to use it.|
|---|
|NOTE 2: 認可サーバーは、「認可コードと DPoP キーの紐付け」 ([I-D.ietf-oauth-dpop] のセクション 10.1 にて定義) のサポートが必要ですが、クライアントがそれを使用することは必須ではありません。|

[認可サーバーの全般的要件](#5321-全般的要件)の項目 12 に記載されているように、認可サーバーが DPoP をアクセストークンの送信者制限メカニズムとして使用する場合、「認可コードと DPoP キーの紐付け」のサポートが必要ですが、これは「クライアントが『認可コードと DPoP キーの紐付け』を使用しなければならない」という意味ではありません。

###### 5.3.3.2. 認可コードフローでの要件

|1. shall use the authorization code grant described in [RFC6749];|
|---|
|1. [RFC6749] で説明されている認可コードグラントを使用しなければならない。|

クライアントは [RFC6749](https://www.rfc-editor.org/info/rfc6749) で指定された認可コードグラント (`response_type=code` および `grant_type=authorization_code`)を使用しなければなりません。

|2. shall use pushed authorization requests according to [RFC9126];|
|---|
|2. [RFC9126] に従ってプッシュ型認可リクエストを使用しなければならない。|

クライアントは PAR ([RFC9126, Pushed Authorization Requests](https://www.rfc-editor.org/info/rfc9126)) を使用しなければなりません。 PAR についての詳細は、「[図解 PAR : OAuth 2.0 Pushed Authorization Requests](https://qiita.com/TakahikoKawasaki/items/97563be46b62a0e02fe6)」が参考になります。

|3. shall use PKCE [RFC7636] with S256 as the code challenge method;|
|---|
|3. PKCE [RFC7636] を使用し、コードチャレンジメソッドとして `S256` を設定しなければならない。|

認可コードの漏洩を防ぐために、クライアントは PKCE ([RFC7636](https://www.rfc-editor.org/info/rfc7636)) を使用しなければなりません。また、`code_challenge_method` パラメーターの値は `S256` に設定しなければなりません。

|4. shall generate the PKCE challenge specifically for each authorization request and securely bind the challenge to the client and the user agent in which the flow was started;|
|---|
|各認可リクエスト毎に PKCE のチャレンジを生成し、そのチャレンジをクライアントおよびフローが開始されたユーザーエージェントに対して安全にバインドしなければなりません。|

PKCE におけるチャレンジの値は各認可リクエスト毎に新規に生成されなければなりません。

|5. shall check the iss parameter in the authorization response according to [RFC9207] to prevent mix-up attacks;|
|---|
|5. mix-up アタックを防ぐため、認可レスポンスの `iss` パラメータを [RFC9207] に従ってチェックしなければならない。|

mix-up アタックはセキュリティリスクの一種であり、クライアントが正当な認可サーバーではなく、悪意のある認可サーバーに認可コードやアクセストークンなどの機密情報を送信してしまうものです。この攻撃はクライアントが複数の認可サーバーとやり取りしており、そのうち少なくとも一つの認可サーバーが攻撃者によって乗っ取られている場合に発生します。攻撃者の目的は、クレデンシャルを傍受して保護されたリソースへの不正アクセスを行うことです。「[OAuth 2.0 Security Best Current Practice の セクション 4.4.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-25#section-4.4.1)」も、具体的に攻撃がどのように実行されるかを説明しています。以下はその概略図です。

![mixup-attack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/ae276188-178d-41cf-a215-fdef620c615c.png)

mix-up アタックを防ぐため、クライアントは認可レスポンスに `iss` パラメーターが含まれており、かつその値が [RFC9207](https://www.rfc-editor.org/info/rfc9207) の通り認可サーバーの発行者 URL と一致することをチェックしなければなりません。

|6. shall only send client_id and request_uri request parameters to the authorization endpoint (all other authorization request parameters are sent in the pushed authorization request according to [RFC9126]);|
|---|
|`client_id` および `request_uri` リクエストパラメーターのみを認可エンドポイントに送信しなければなりません (それ以外のすべての認可リクエストパラメーターは、[RFC9126] に従ってプッシュ型認可リクエストで送信されます)。|

認可エンドポイントに認可リクエストを送信する際は、`client_id` と `request_uri` のみを含めることが許されます。

|7. if using [OIDC], should not use nonce parameter values longer than 64 characters.|
|---|
|[OIDC] を使用する場合、64 文字を超える nonce パラメーターを使用すべきではありません。|

OIDC を使用する場合、`nonce` パラメーターの長さは 64 文字以下にすべきです。

|NOTE 1: The recommended restrictions on the nonce parameter value length is to aid interoperability.|
|---|
|NOTE 1: nonce パラメーターの長さを推奨通りに制限することで、相互運用性を高めることができます。|

文言の通りです。

#### 5.3.4. リソースサーバーの要件

|1. shall accept access tokens in the HTTP header as in Section 2.1 of OAuth 2.0 Bearer Token Usage [RFC6750] or Section 7.1 of DPoP [RFC9449];|
|---|
|1. OAuth 2.0 Bearer Token Usage [RFC6750] の セクション 2.1 または DPoP [RFC9449] のSection 7.1 に記載されている通り、HTTP ヘッダーでアクセストークンを受け入れなければならない。|

[RFC6750](https://www.rfc-editor.org/info/rfc6750) で定義される Bearer トークン形式、または [RFC9449](https://www.rfc-editor.org/info/rfc9449) で定義される DPoP トークン形式を利用して送信されるアクセストークンをリソースサーバーは受け入れなければなりません。

|2. shall not accept access tokens in the query parameters stated in Section 2.3 of OAuth 2.0 Bearer Token Usage [RFC6750];|
|---|
|2. OAuth 2.0 Bearer Token Usage [RFC6750] のセクション 2.3 で規定されるクエリパラメータで指定されたアクセストークンは受け入れてはならない。|

[RFC6750](https://www.rfc-editor.org/info/rfc6750) のセクション 2.3 では、クエリパラメーターにアクセストークンを含める方法が規定されていますが、リソースサーバーはセキュリティ上の理由からそのようなアクセストークンを拒否しなければなりません。

|3. shall verify the validity, integrity, expiration and revocation status of access tokens;|
|---|
|3. アクセストークンの有効性、完全性、有効期限、および失効状態をチェックしなければなりません。|

これはリソースサーバーがアクセストークンに関して以下を確認する必要があることを意味します:

- **有効性**: アクセストークンが正当な認可サーバーによって発行されたものであることを確認する。
- **完全性**: アクセストークンが転送中に改竄されたり、変更されていないことを確認する。
- **有効期限**: アクセストークンの有効期限が切れていないことを確認する。
- **失効状態**: アクセストークンが有効期限前に失効または無効化されていないかを確認する。

|4. shall verify that the authorization represented by the access token is sufficient for the requested resource access and otherwise return errors as in Section 3.1 of [RFC6750];|
|---|
|4. アクセストークンに付与された権限が、リクエストされたリソースへのアクセスに対して十分であるかをチェックし、そうでない場合は [RFC6750] のセクション 3.1 に規定されている通りにエラーを返さなければなりません。|

リソースサーバーはアクセストークンのスコープが、「リクエストされたリソースのアクセスに必要なスコープ」を含んでいるのかをチェックしなければなりません。もし不十分な場合、[RFC6750 のセクション 3.1](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1) に指定されている通り、エラーを返さなければなりません。

|5. shall support and verify sender-constrained access tokens using one or both of the following methods:<br>&nbsp;&nbsp;•MTLS as described in [RFC8705],<br>&nbsp;&nbsp;•DPoP as described in [RFC9449].|
|---|
|5. 以下の方法のいずれかまたは両方を使用して送信者制限されたアクセストークンをサポートし、検証しなければなりません:<br>&nbsp;&nbsp;•[RFC8705] で説明されている MTLS<br>&nbsp;&nbsp;•[RFC9449] で説明されている DPoP|

これに関する詳細は、[認可サーバーの全般的要件](#5321-全般的要件)の項目 5 を参照ください。

### 5.4. 暗号化とシークレット

#### 5.4.1. 全般的要件

|1. Authorization servers, clients, and resource servers when creating or processing JWTs shall<br>&nbsp;&nbsp;1. adhere to [RFC8725];<br>&nbsp;&nbsp;2. use PS256, ES256, or EdDSA (using the Ed25519 variant) algorithms; and<br>&nbsp;&nbsp;3. not use or accept the none algorithm.|
|---|
|1. JWT を作成または処理する際、認可サーバー・クライアント・リソースサーバーは、<br>&nbsp;&nbsp;1. [RFC8725] に従うべきです;<br>&nbsp;&nbsp;2. `PS256`、`ES256`、または (`Ed25519` 形式を使用する) `EdDSA` アルゴリズムのどれかを使用する必要があります; そして<br>&nbsp;&nbsp;3. `none` アルゴリズムを使用してはなりませんし、受け入れてもなりません。|

[RFC8725](https://www.rfc-editor.org/rfc/rfc8725.html) は、JWT に関するベストプラクティスを解説したものです。概要は以下の通りです。

- **アルゴリズムの検証**: ライブラリは、ユーザーがサポートされているアルゴリズムを選択できるように設計されていなければならず、サポート外のアルゴリズムを使用した暗号操作を禁止しなければなりません。
- **適切なアルゴリズムの使用**: アプリケーションは、そのセキュリティ要件に合致し、現時点で安全とされる暗号アルゴリズムを使用する必要があります。使用するアルゴリズムは、既存のアルゴリズムの脆弱性等により時間と共に変化するため、アプリケーションは柔軟に設計されていなければなりません。
- **暗号化操作の検証**: JWT に関する全ての暗号化操作の結果は検証しなければならず、そのいずれかが失敗した場合はその JWT を拒否しなければなりません。
- **暗号化のインプットの検証**: 暗号化処理のインプットは検証されなければなりません。
- **鍵のエントロピー**: 脆弱な対称鍵を避ける等の理由で、鍵のエントロピーは十分でなければなりません。
- **UTF-8 エンコーディングの使用**: JSON 仕様に準拠し、エンコーディングおよびデコーディングに UTF-8 を使用しなければなりません。
- **issuer と subject の検証**: アプリケーションは issuer と subject を検証し、期待値と合致しない場合はその JWT を拒否しなければなりません。
- **audience の検証**: アプリケーションは JWT の audience を検証し、合致しない場合はその JWT を拒否しなければなりません。
- **暗号化前の圧縮**: 情報漏洩を防ぐため、データの暗号化前の圧縮は避けるべきです。
- **受け取ったクレームに関する注意**: アプリケーションは `kid` やヘッダーの URL などの受け取ったクレームの脆弱性に注意しなければなりません。
- **JWT の明示的なタイプ**: 異なる種類の JWT の混同を防ぐため、`typ` ヘッダーパラメータの使用が推奨されます。
- **別個の検証ルール**: 同一の発行元が異なる種類の JWT を発行する場合、それらの JWT の誤用を防ぐために、それぞれに対して別個の検証ルールを使用することが推奨されます。

また、クライアントアサーションなどの JWT に対して検証可能な署名を生成するために、安全かつ現代的な署名アルゴリズム ー`PS256`、`ES256`、(`Ed25519` 形式を使用する) `EdDSA` ー を使用することが要求されます。

また、`none` アルゴリズムの使用および受け入れは許されていません。

|2. RSA keys shall have a minimum length of 2048 bits.<br>3. Elliptic curve keys shall have a minimum length of 224 bits.|
|---|
|2. RSAキーは最低 2048 ビットの長さでなければならない。<br>3. 楕円曲線キーは最低 224 ビットの長さでなければならない。

- RSA キーは 2048 ビット以上の長さでなければなりません。
- EC キーは 224 ビット以上の長さでなければなりません。

|4. Credentials not intended for handling by end-users (e.g., access tokens, refresh tokens, authorization codes, etc.) shall be created with at least 128 bits of entropy such that an attacker correctly guessing the value is computationally infeasible. Cf. Section 10.10 of [RFC6749].|
|---|
|4. エンドユーザーによって取り扱われることが想定されていないクレデンシャル (例えば、アクセストークン、リフレッシュトークン、認可コードなど) は、計算困難性を保証するために、少なくとも 128 ビットのエントロピーで作成しなければなりません。参照: [RFC6749], セクション 10.10|

アクセストークンや認可コードなど、エンドユーザーに直接取り扱われない想定のクレデンシャルは、少なくとも 128 ビットのエントロピーを用いて生成されることが推奨されます。これにより、これらの値の計算困難性が保証され、不正なアクセスや攻撃のリスクを回避できます。

#### 5.4.2. JSON Web Key Sets

本プロファイルは、`private_key_jwt` の使用をサポートしており、さらに OpenID Connect の使用も許容しています。これらが使用される場合、クライアントおよび認可サーバーは、他のパーティーが提供する鍵を用いてペイロードを検証する必要があります。

認可サーバーにおいては、公開鍵の配布手段として JWKS URI エンドポイントの使用が強く推奨されます。

クライアント側の鍵管理においては、JWKS URI エンドポイントの使用、あるいは [RFC7591](https://datatracker.ietf.org/doc/rfc7591/) および [RFC7592](https://datatracker.ietf.org/doc/rfc7592/) と組み合わせた `jwks` パラメーターの使用が推奨されます。

認可サーバーの `jwks_uri` の定義は [RFC8414](https://datatracker.ietf.org/doc/rfc8414/) に、クライアントの jwks_uri の定義は [RFC7591](https://datatracker.ietf.org/doc/rfc7591/) にそれぞれ記載されています。

さらに、`jwks_uri` エンドポイントを提供するいかなるサーバーも、以下の要件を満たす必要があります:
- `jwks_uri` エンドポイントは TLS を用いて提供しなければなりません。
- `x5u` および `jku` の JOSE ヘッダーは 使用すべきではありません。
- 同一の `kid` を持つ複数の鍵を含む JWK セットを 提供すべきではありません。

#### 5.4.3. 重複する鍵 ID の処理

JWK セットには、同じ `kid` を持つ複数の鍵を含めるべきではありません。
しかしながら、相互運用性を高めるために、`kid` が重複している場合、検証者は JWS メッセージの検証に使用する鍵を選択する際に、`kty`、`use`、`alg` など他の JWK 属性も考慮しなければなりません。

例えば、署名の検証に使用する鍵の選択には、以下のようなアルゴリズムが利用できます:
1. JOSE ヘッダー内の `kid` と一致する鍵を JWK セットから探します。
2. 一致する鍵が 1つだけ 見つかった場合は、その鍵を使用します。
3. 一致する鍵が複数存在する場合は、`alg`、`use`、`kty`、`crv` などの属性がメッセージと一致する鍵を見つけるまで順に確認し、該当する鍵を使用します。

### FAPI 1.0 との主要な違い

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|JAR|PAR|

JAR (署名付き認可リクエスト) は、リクエストの改竄を防ぐために使用されていましたが、JWT の生成や署名がクライアント実装にとって負担となり、相互運用性の課題もありました。FAPI 2.0 では、認可リクエストを事前にバックチャネルで送信する PAR (プッシュ型認可リクエスト) が必須となり、フロントチャネルに依存せず、より安全かつ一貫性のあるリクエスト整合性が確保されるとともに、JWT を必須としないことで実装負荷が軽減され、互換性も向上しました。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|JARM|認可レスポンス内には `code` のみ|

FAPI 1.0 - Part 2: Advanced では、認可レスポンスに ID トークンなどの意味を持つ情報が含まれていたため、フロントチャネルでの改竄防止を目的として、レスポンス全体を JWT に署名する [JARM](https://openid.net/specs/oauth-v2-jarm-final.html) が使用されていました。一方、FAPI 2.0 では、認可レスポンスに認可コードのみを含めるよう限定し、ID トークンなどの重要な情報はすべてバックチャネル (トークンエンドポイント) で取得する構造に変更されました。これにより、JARM による整合性の担保が不要となりました。結果として、JARM を廃止することで実装の簡素化と相互運用性の向上が実現されています。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|BCM 原則に基づく設計|攻撃者モデルと BCP に基づく設計|

FAPI 1.0 - Part 2: Advanced では、Basin-Cremers-Meier (BCM) 原則に沿って個別の脅威ごとに対策を実装する形をとっていました。FAPI 2.0 では、攻撃者モデルとセキュリティ目標を明確に定義した上で、OAuth Security BCP に準拠した設計方針が採用され、より一貫性のある形でセキュリティが設計されています。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|s_hash|PKCE|

FAPI 1.0 - Part 2: Advanced では、クロスサイトリクエストフォージェリ (CSRF) 対策として `state` の整合性を `s_hash` によって保護していました。FAPI 2.0 では、CSRF 対策は PKCE によって実現され、`state` の整合性は PAR によって間接的に担保される形になりました。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|リダイレクト URI の事前登録|PAR で指定可能|

FAPI 1.0 - Part 2: Advanced では、クライアントのリダイレクト URI はあらかじめ登録しておく必要がありました。FAPI 2.0 では、PAR とクライアント認証を組み合わせることで、リダイレクト URI 事前登録が不要となり、柔軟性が向上しました。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|code または code id_token|code のみ|

FAPI 1.0 - Part 2: Advanced では、認可レスポンスに認可コードとともに ID トークンが含まれることがありました。そのため、クライアントは認可レスポンスの改竄やリプレイアタックを防ぐために、ID トークンの署名検証および nonce の検証を実施する必要がありました。一方、FAPI 2.0 では、認可レスポンスには認可コードのみが含まれ、ID トークンを取得する際はバックチャネル (トークンエンドポイント) を経由する形となりました。その結果、認可レスポンスを取得した段階でクライアントが ID トークンの署名検証や nonce 検証を行う必要がなくなり、これらのチェックはスキップできるようになりました。ただし、認可コードを保護する目的で、PKCE は認可サーバーによって強制されています。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|ID トークンを署名検証に使用|PKCE|

FAPI 1.0 - Part 2: Advanced では、ID トークンがリクエストとレスポンスの整合性確認に利用されていました（detached signature）。FAPI 2.0 では、PKCE によって認可コードの整合性が確実に保証されるため、ID トークンはその役割から解放されました。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|フロントチャネルで ID トークンを暗号化|ID トークンはバックチャネルのみ|

FAPI 1.0 - Part 2: Advanced では、ID トークンをフロントチャネルで安全に扱うために暗号化が必要となるケースがありました。FAPI 2.0 では、ID トークンはすべてバックチャネル経由で取得されるため、暗号化の必要がなくなり、実装が簡素化されました。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|リクエストオブジェクトに nbf/exp を含める|request_uri に有効期限を持たせる|

FAPI 1.0 - Part 2: Advanced では、リクエストの有効期限を `nbf` や `exp` によって管理していました。FAPI 2.0 では、PAR によって発行された `request_uri` に有効期限が自動的にサーバーから付与されるため、事前生成されたリクエストの悪用を防止する設計となっています。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|x-fapi-* ヘッダーを仕様に含める|実装ガイドラインに分離|

FAPI 1.0 - Part 2: Advanced では、`x-fapi-*` ヘッダーがセキュリティプロファイルの一部として定義されていました。FAPI 2.0 では、これらの実装関連の情報は別ドキュメント (Implementation and Deployment Advice) に分離され、プロファイル本体はセキュリティ要件に集中するよう整理されました。

|FAPI 1.0 - Part 2: Advanced|FAPI 2.0|
|---|---|
|MTLS によるトークンの送信者制限|MTLS または DPoP によるトークンの送信者制限|

FAPI 1.0 - Part 2: Advanced では、アクセストークンの送信者制限を MTLS によって実現していました。FAPI 2.0 では、TLS に依存しない DPoP の利用も認められ、導入のしやすさと柔軟性が向上しています。

:::note warn
FAPI 1.0 についての詳細については、「[実装者による Financial-grade API (FAPI) 解説](https://qiita.com/TakahikoKawasaki/items/83c47c9830097dba2744)」が参考になります。
:::

### 6. セキュリティ考慮事項

#### 6.1. アクセストークンの寿命

- アクセストークンは短命にすることが推奨されます。これは、アクセストークンが漏洩した場合でも、攻撃者が悪用できる時間を短くできるためです。

- リフレッシュトークンと短命なアクセストークンを組み合わせて使う構成が理想的です。リフレッシュトークンがあることで、クライアントはアクセストークンを更新し続けられます。

- リフレッシュトークンを使うことで、送信者制限のための鍵を定期的にローテーションすることも可能です。鍵の漏洩やセキュリティ強化のための定期的な鍵交換に有効です。

- 長期間 (数日〜数週間) 有効な認可を維持する必要がある場合でも、アクセストークン自体は短命 (数分〜数時間) に設定し、リフレッシュトークンで対応するのが望ましいです。

##### 注意
アクセストークンの寿命を短くしすぎると、リフレッシュの頻度が増えるため、認可サーバーへの負荷や依存度が高まり、パフォーマンスや耐障害性のトレードオフが発生します。

#### 6.2. DPoP proof の再利用 (リプレイ)

##### 想定される攻撃

攻撃者 ([タイプ A5](https://openid.net/specs/fapi-attacker-model-2_0-final.html#section-7.7)) は、ユーザーの DPoP proof を取得し、それを再利用 (リプレイ) する可能性があります。また、DPoP は HTTP リクエストのボディや多くのヘッダーを署名しないため、証明を再利用して内容を改変したリクエストを送信できるリスクがあります。例えば、支払いリクエストにおいて送金額や送金先口座をすり替えるといった攻撃が考えられます。

##### 考えられる対策

1. **短命な DPoP Nonce の利用**
リソースサーバーが有効期間が短い nonce を発行することで、リクエストの再利用できる時間を制限します。

2. **`jti` によるリプレイ防止**
各 DPoP proof に一意の ID (JWT ID) を付与し、過去に使用されたものをサーバー側で記録・拒否する。

3. **FAPI Message Signing の利用**
リクエスト本体を署名対象に含めることで、内容の改変と再利用を防止します。

4. **MTLS の利用**
DPoP の代替として、より厳格な送信者制限（sender-constraining）手法である MTLS（相互 TLS）が考えられます。

##### 注意

これらの対策は、実装の複雑さやパフォーマンス・スケーラビリティに影響を与える可能性があります。  
攻撃者タイプ A5 は高度な攻撃者モデルであり、多くのエコシステムでは必ずしもこれらの対策をすべて導入する必要はありません。

#### 6.3. 盗まれたアクセストークンのインジェクション

攻撃者が盗んだアクセストークンをクライアントにインジェクションし、そのアクセストークンをあたかも正規の認可フローで取得したように見せかけて使用することで、MTLS（RFC 8705）や DPoP（RFC 9449）による送信者制限を回避する可能性があります。これは FAPI 1.0 に記載されている「Cuckoo's Token Attack (カッコウのトークン攻撃)」に相当します。

##### 前提

この攻撃が成立するためには、攻撃者が以下のいずれかの方法で、クライアントに信頼された認可サーバーを乗っ取る必要があります。

- クライアントが信頼している別の認可サーバーを侵害する。
- 認可サーバーとして振る舞い、ソーシャルエンジニアリングを利用してクライアントとの信頼関係を構築する。
- クライアントそのものを侵害する。

中央ディレクトリやその他のリソースサーバーのディスカバリ機構が存在し、それによって攻撃者が管理する認可サーバーから取得した盗まれたアクセストークンを、クライアントが正規のリソースサーバーに送信するよう誘導できる場合、この攻撃はより容易になる可能性があります。

##### 対抗策

このような攻撃は前提条件が厳しく、すべてのエコシステムにおいて想定する必要はありませんが、以下のような対策が有効です。

- 認可サーバーごとに異なる DPoP キーや MTLS 証明書を使用する。
- クライアントがアクセストークンの発行者（issuer）をリソースサーバーに送信し、リソースサーバー側で正当性を確認する。 
*現時点でこれを行うための標準仕様は存在しません。
- アクセストークンの有効期限を短く設定し、リフレッシュトークンと併用することで、攻撃可能な時間を短縮する。

この種の攻撃に対して対策を導入するかどうかは、各エコシステムの脅威モデルに基づいて慎重に判断することが重要です。

#### 6.4. 認可リクエストの漏洩による CSRF

攻撃者 ([タイプ A3](https://openid.net/specs/fapi-attacker-model-2_0-final.html#section-7.5)) が認可リクエストを傍受できた場合、次のような攻撃が可能になります。

1. 攻撃者がそのリクエストを使って認可サーバーにログインし、自身のアクセストークンや認可コードを取得する。
2. その後、**クロスサイトリクエストフォージェリ (CSRF) 攻撃**を通じて、正規ユーザーをクライアントにリダイレクトさせ、**攻撃者自身の認可コードを使わせる**。
3. その結果、正規ユーザーが攻撃者のリソースにアクセスしてしまい、セッションの整合性が崩れる。

##### 前提条件

この攻撃は、攻撃者が短時間で以下の処理を実行できるだけの能力を持っていることを前提としています:

- 認可リクエストを読み取ることができる (ログファイルやサイドチャネル経由など)。
- ユーザーに対して CSRF 攻撃を仕掛けられる。

リダイレクトベースの認可フローはすべて、構造上、ユーザーとクライアント間のセッションと、ユーザーと認可サーバー間のセッションを厳密に結び付けることができないため、この攻撃に対して脆弱です。

##### 対抗策

このような攻撃への対策として、以下の方法が挙げられます：

1. **認可サーバーの取り決めとして、`request_uri` の使用回数を一度限りとする。**  
攻撃者がリクエストを読めたとしても、正規ユーザーが先にその request_uri を含む認可リクエストを送信していれば攻撃は成立しなくなります。

2. **クライアント側の取り決めとして、一回の認可エンドポイント呼び出しにつき、トークンエンドポイントへの認可コードの送信は 一度限りとする。**
攻撃者がユーザーより先に認可コードをトークンエンドポイントに送れない場合、攻撃は失敗します。

3. **認可コードの有効期限を短くする**
攻撃者が攻撃を完了させるまでの時間を制限することで、攻撃の成功率を下げます。

##### 補足

攻撃者がユーザーのリクエストを完全にブロックできる場合、先述の一つ目と二つ目の対策は回避できてしまいます。しかし現実的には、攻撃者が実行可能なのは、認可リクエストを読み取ること (例: ログファイルやサイドチャネルなど) であり、ユーザーからのリクエスト自体をブロックすることは困難です。ただし、ユーザーのインターネット接続が遅い場合は、攻撃者が先にリクエストを使用する余地が生まれるため、攻撃の成功確率がわずかに高まる可能性があります。

#### 6.5. ブラウザすり替え攻撃

攻撃者が、被害者のブラウザを通じて送信された認可レスポンスにアクセスできる場合、以下のような「ブラウザすり替え攻撃」が可能です。

1. 攻撃者は自身のブラウザとクライアントを用いて認可フローを開始し、認可サーバーに対してプッシュ型認可リクエストを送信します。
2. 認可サーバーから `request_uri` が返却され、クライアントは攻撃者のブラウザを認可サーバーへリダイレクトします。
3. 攻撃者はこのリダイレクト URL を傍受し、被害者に転送します (例: フィッシングサイト、メール、QR コードなどに URL を埋め込みます)。
4. 被害者はこれを正規の認証・認可フローと誤認し、認可サーバーでログインし、アクセスを許可してしまう可能性があります。
5. 攻撃者は、被害者のブラウザに表示された認可レスポンスを取得し、それを自身のブラウザへ転送します。
6. クライアントは、もともとこのフローを開始したのが攻撃者のブラウザであると認識しているため、正常なレスポンスとして受け入れて、アクセストークンやユーザー情報を取得します。
7. 結果として、攻撃者はクライアント経由で被害者としてログインした状態、または被害者のリソースへのアクセス権限を獲得します。

##### 対応の困難さ

現状のリダイレクトベースのプロトコルでは、認可レスポンスが漏洩した場合にこの攻撃を完全に防ぐ手段は存在しません。そのため、この仕様では以下のような手段で認可レスポンスの機密性を守ることを重視しています:

- オープンリダイレクタの禁止
- `redirect_uri` の事前登録と検証。
- 認証・暗号化されたチャネル (例：HTTPS) で `redirect_uri` をやり取りする。
- PAR によるフロントチャネルからのリクエスト情報の排除。

##### 実装者への注意

この攻撃は、認可レスポンスの漏洩を前提としたものです。特にモバイルアプリなど他の文脈でこのプロファイルを適用する場合には、認可レスポンスの機密性を最重要事項として扱う必要があります。

#### 6.6. 不完全または誤った実装

本ドキュメントおよび、その基盤となる OpenID Connect や OAuth の仕様を 完全かつ正確に実装することは、セキュリティと相互運用性の恩恵を最大限に得るために極めて重要です。

##### 検証手段

OpenID Foundation では、実装が正しく行われているかどうかを確認するためのテストツールを提供しています:

- [https://openid.net/certification/](https://openid.net/certification/)

また、すでに認定された実装の一覧も公開されています:

- [https://openid.net/developers/certified/](https://openid.net/developers/certified/)

##### 推奨事項

本プロファイルを利用するシステムは、OpenID Foundation によって認証された実装 (certified implementation) を使用するべきです。これにより、セキュリティリスクや実装上の相違によるトラブルを未然に防ぐことができます。

#### 6.7. クライアントによるリソースオーナーなりすまし

[OAuth 2.0 Security Best Current Practice](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-29) のセクション 4.15 では、悪意のあるクライアントが、自身の `client_id` をリソースオーナーのサブジェクト識別子と誤認させるよう細工を施す攻撃について言及しています。この攻撃が成立するためには、以下の条件が必要です。

- クライアントが `client_id` の値を自由に操作できる。
- 認可サーバーが、クライアントとエンドユーザーの両方に対して、同等の権限を持つアクセストークンを発行している。

##### 推奨事項

このような攻撃を防ぐために、認可サーバーは次の点に注意する必要があります。

- クライアントが `client_id` を自由に指定・操作できないようにすること。
- `client_id` が、エンドユーザーの subject (`sub`) と混同される形式にならないように設計すること。

これらの対策を行うことで、クライアントによるリソースオーナーのなりすましのリスクを軽減できます。

#### 6.8. 鍵の漏洩

暗号鍵が漏洩した場合、その影響を最小限に抑えるために以下の対策が推奨されます。

##### 鍵のローテーション

鍵の定期的な自動ローテーションを行うことで、漏洩した鍵の使用可能な時間を短縮することができます。`jwks_uri` エンドポイントを利用すれば、手動による鍵の配布や同期を必要とせず、安全かつ効率的に鍵を更新することが可能です。

##### 鍵の用途

鍵は単一の目的に限定して使用することが推奨されます。例えば、署名と暗号化を同一の鍵で行うべきではありません。詳細は [NIST Special Publication 800-57 Part 1 Revision 5](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf) のセクション 5.2 を参照してください。

##### ステートフルなクレデンシャル

鍵によって署名されたステートレスなトークンを使用している場合、署名鍵が漏洩してしまうと、攻撃者がトークンを偽造できてしまうリスクがあります。ステートフルなトークンを用いて中央集権的に管理することよって各トークンの有効性を検証できる設計にすることで、このリスクを低減できます。一方で、ステートレスなトークンには以下の利点があります:

- トークン自体に必要な情報が含まれているため、リソースサーバーはデータベースを参照せずにトークンを検証できます。
- 認可サーバーに依存せずにトークンの検証が可能なため、パフォーマンスやスケーラビリティに優れます。
- 認可サーバーとリソースサーバーが分離された環境において特に有効です。（[RFC9068](https://datatracker.ietf.org/doc/rfc9068/) 参照）

トークンの設計においては、セキュリティと運用効率のトレードオフを慎重に評価する必要があります。

##### クレデンシャル間の関連性

一つの認可処理で複数のクレデンシャルが発行される場合、それらの関連性を明確にしておくことが推奨されます。これにより、ある一つのクレデンシャルが漏洩・不正使用された場合でも、関連する他のクレデンシャルをまとめて無効化することが可能になります。

### 7. プライバシーに関する考慮事項

本ドキュメントを実装する際には、多くのプライバシー関連の要素を考慮する必要があります。本仕様は OAuth 2.0 および OpenID Connect に関連するプロファイルであるため、下記の事項は、本仕様固有のプライバシーリスクというよりは、OAuth または OpenID Connect 全体に共通するものと言えます。実装者は、プライバシー影響評価 (PIA) を実施し、特定されたリスクに適切に対処することが推奨されます。

*参考資料として [ISO/IEC 29100](https://www.iso.org/standard/85938.html) および [ISO/IEC 29134](https://www.iso.org/standard/86012.html) があげられます。

#### 主なプライバシー上の脅威と懸念事項

- **不適切なプライバシー通知**
(例えば `policy_url` 上で) 利用者に提示されるプライバシーポリシーが不十分または不適切な場合があります。

- **同意画面における選択肢の不足**
選択肢が十分でない同意画面では、真の意味での「同意」を得られません。

- **データの目的外利用**
認可サーバー、リソースサーバー、クライアントのいずれかが、ユーザーの同意内容とは異なる内容の目的でデータを使用する可能性があります。

- **収集最小化の原理の違反**
目的のために必要なデータよりも多くのデータをクライアントが要求する場合を指します。

- **リソースサーバーからの不要な個人データの提供**
悪質または不適切な実装のリソースサーバーが、クライアントの要求を超える個人データを返す可能性。

- **データ最小化の違反**
必要以上のデータを処理することは、データ最小化の原則の違反にあたります。

- **認可サーバーによるエンドユーザーのトラッキング**
どのクライアントにどのエンドユーザーのどんなデータが提供されたかを認可サーバーが記録・追跡する行為を指します。

- **クライアントによるエンドユーザーのトラッキング**
2 つ以上のクライアントが、アクセス・トークンや ID トークンを照合してユーザーを追跡する行為を指します。

- **エンドユーザーによるクライアントの誤認**
認可画面上でクライアントに関する情報表示が不明瞭である場合、ユーザーがどんなクライアントなのかを誤認するリスクがあります。

- **エンドユーザーがデータ提供に関して十分に理解していない**
エコシステムの信頼性を向上させるには、認可リクエストの内容 (どのデータがクライアントに共有されるか) を、ユーザーが十分に理解できるようにすることが重要です。

- **認可リクエスト/レスポンスに含まれる個人データの漏洩**
本プロファイルは、認可リクエストおよびレスポンスで送信されるデータを可能な限り最小限に抑えることを目指していますが、それでも攻撃者が一部のデータを傍受する可能性があります。

- **認可サーバーからのデータ漏洩**
認可サーバーが侵害された場合、保有している個人データが漏洩または改竄される可能性があります。

- **リソースサーバーからのデータ漏洩**
リソースサーバーも個人データを保持することがあり、侵害による漏洩のリスクがあります。

- **クライアントからのデータ漏洩**
一部のクライアントは個人データを保持しており、侵害された場合にそのデータが漏洩・改竄されるリスクがあります。

### 8. IANA に関する考慮事項

#### 8.1. OAuth Dynamic Client Registration のメタデータの登録

本仕様では、[RFC7591](https://datatracker.ietf.org/doc/rfc7591/) により定義された IANA の "OAuth Dynamic Client Registration Metadata" レジストリへの、以下のクライアントメタデータの登録を要求します。

#### 8.1.1. 登録内容

|クライアントメタデータ名|説明|
|---|---|
|`use_mtls_endpoint_aliases`|認可サーバーのメタデータにおいて宣言される MTLS エンドポイントエイリアス ([RFC8705](https://datatracker.ietf.org/doc/rfc8705/) 参照) をクライアントが使用する必要があることを示すフラグです。このフラグが `true` の場合、MTLS エンドポイントエイリアスの利用用途は、クライアント認証やアクセストークンの送信者制限に限定されず、より広範な用途で利用されることが求められます。|

## 最後に

![authlete-logo-horizontal_wclear.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60350/8e160e92-83f6-34fb-f718-3ada9db8b87b.png)

最後に、私が共同創業した [Authlete, Inc.](https://www.authlete.com/) が提供する [Web API](https://docs.authlete.com) は、**FAPI 1.0 および FAPI 2.0 の両者**をサポートし、かつ [FAPI OpenID Provider Certification Program](https://openid.net/certification/) に認定されております。

ご興味がある場合、[こちらのウェブフォーム](https://www.authlete.com/contact/)または以下のメールアドレスよりお気軽にお問い合わせください。

- **ライセンスおよび契約**: [sales@authlete.com](mailto:sales@authlete.com)
- **パートナーシップ**: [bizdev@authlete.com](mailto:bizdev@authlete.com)
- **技術サポート**: [support@authlete.com](mailto:support@authlete.com)

また、下記のチェックも是非よろしくお願い致します。

- [GitHub](https://github.com/authlete)
- [Qiita](https://qiita.com/organizations/authlete)
- [Zenn](https://zenn.dev/p/authlete)
- [Facebook](https://www.facebook.com/authlete)
- [X (Twitter)](https://twitter.com/authlete)
- [Linkedin](https://www.linkedin.com/company/authlete)
- [YouTube](https://www.youtube.com/channel/UCERMcUO2vR7F96Qd-BZbiwA)

最後までご拝読いただきありがとうございます。FAPI 2.0 に関する今後のアップデートにご期待ください。

## 更新情報

2024 年 4 月 16 日: FAPI 2.0 セキュリティプロファイル (ID2) に関する解説を公開。
2025 年 6 月 2 日: FAPI 2.0 セキュリティプロファイルの解説内容を Final 版に対応するよう更新。(ID2 の解説記事は[こちら](https://qiita.com/hidebike712/items/020a4cc2a95f4ab47965/revisions)のプレビューをご覧ください。)