
# OAuth 2.0 および OpenID Connect のエンドポイント

> **ステータス: `planned`。** このページでは、計画（§13）で定められた、すべての KeenAuth 環境のプロトコル機能について説明します。エンドポイントはフェーズ 2 で構築中であり、ホスト型環境ではまだ利用できません。一般提供までに詳細が変更される可能性があります。

すべての環境は、それぞれ独立した OAuth 2.0 認可サーバーであり、OpenID Connect プロバイダーです。エンドポイントは管理 API の一部ではなく、環境のホスト `https://<environment-slug>.<region>.keenauth.app` または検証済みのカスタムドメイン上にあります。表中の `<issuer>` は環境の発行者であり、ディスカバリードキュメントの `issuer` の値を指します。

## エンドポイント

| エンドポイント | メソッドとパス | クライアント認証 |
|---|---|---|
| ディスカバリー | `GET <issuer>/.well-known/openid-configuration` および `GET <issuer>/.well-known/oauth-authorization-server`（RFC 8414、内容は同じ） | なし |
| 鍵 | `GET <issuer>/.well-known/jwks.json` | なし |
| 認可 | `GET` または `POST <login host>/oauth2/authorize` | なし（ブラウザー） |
| 事前プッシュ認可リクエスト（RFC 9126） | `POST <issuer>/oauth2/par` | 機密クライアントでは必須。パブリッククライアントでは `client_id` |
| トークン | `POST <issuer>/oauth2/token` | 機密クライアントでは必須。パブリッククライアントでは `client_id`（DPoP は任意） |
| デバイス認可（RFC 8628） | `POST <issuer>/oauth2/device_authorization` | トークンエンドポイントと同じ |
| 取り消し（RFC 7009） | `POST <issuer>/oauth2/revoke` | トークンエンドポイントと同じ |
| イントロスペクション（RFC 7662） | `POST <issuer>/oauth2/introspect` | 機密クライアントのみ |
| UserInfo | `GET` または `POST <issuer>/oauth2/userinfo` | Bearer または DPoP のアクセストークン |
| セッション終了 | `GET` または `POST <login host>/oauth2/logout` | なし（`id_token_hint` または `client_id`） |

`<login host>` は、環境のサインインドメントのいずれかを指します。デフォルトのホストまたは追加されたカスタムドメインのいずれかです。ディスカバリードキュメントは発行者のホストでのみ提供されます。別のサインインホストで `/.well-known/openid-configuration` にアクセスすると、本文に発行者の URL を含む `404` が返されます。

## グラントタイプ

| グラント | 用途 |
|---|---|
| `authorization_code` | ブラウザーおよびネイティブアプリでのサインイン。`S256` による PKCE が必須です。 |
| `refresh_token` | トークンを更新します。使用するたびにリフレッシュトークンがローテーションされ、古いトークンを再利用すると、トークンファミリー全体が取り消されます。 |
| `client_credentials` | マシン間のアクセス。 |
| `urn:ietf:params:oauth:grant-type:device_code` | テレビやコマンドラインツールなど、キーボードのないデバイス。 |
| `urn:ietf:params:oauth:grant-type:token-exchange` | サービス間の委任およびなりすまし。 |

暗黙的フロー（`response_type=token` および `id_token` を含むすべての指定）、リソースオーナーパスワード資格情報グラント、ハイブリッドレスポンスタイプは、現在も将来もサポートされません。RFC 9700 では最初の 2 つが禁止されています。

## デバイス認可

ブラウザーのないデバイスは、`POST <issuer>/oauth2/device_authorization` を呼び出してフローを開始します。デバイスグラントを明示的に指定した `device` または `native` 型のアプリケーションだけが利用できます。レスポンスには `device_code`、`user_code`、および確認用のアドレスが含まれます。ユーザーは別のデバイスでそのアドレスを開き、サインインして承認します。その間、デバイスは `grant_type=urn:ietf:params:oauth:grant-type:device_code` を指定してトークンエンドポイントを定期的に問い合わせます。`user_code` は 8 文字で、`XXXX-XXXX` の形式で表示されます。デバイスコードの有効期間は 10 分間で、一度だけ使用できます。デバイスのポーリング間隔は最短 5 秒です。これより速くポーリングすると `slow_down` が返され、間隔に 5 秒が加算されます。`verification_uri` は `https://<login host>/u/device` です。ユーザーには、承認前に、アプリケーション、要求されたスコープ、およびリクエストを開始したデバイスの国が表示されます。

## セキュリティルール

環境は、例外なく OAuth 2.0 セキュリティベストカレントプラクティス（RFC 9700）に従います。

- リダイレクト URI は、登録済みの URI とバイト単位で一致しなければなりません。ワイルドカードは使用できません。
- PKCE は `S256` のみを受け付け、`plain` は常に拒否されます。PKCE はパブリッククライアントで必須であり、すべてのアプリケーションでデフォルトで有効です。機密の `web` アプリケーションでは設定から無効にできますが、その場合も環境が `nonce` を必要とする場合に限ります。
- 公式 SDK は 128 ビットの `state` と `nonce` を送信し、戻り時に両方を検証します。
- 認可コードの有効期間は 60 秒で、一度だけ使用できます。使用済みのコードを提示すると `invalid_grant` が返され、最初の使用で発行されたリフレッシュトークンとアクセストークンが取り消されます。
- 事前プッシュ認可リクエストでは、リクエストパラメーターがブラウザーのアドレスバーに表示されません。すべてのプランで利用でき、`require_par` 設定により、アプリケーションまたは環境全体で必須にできます。
- リフレッシュトークンは使用するたびにローテーションされ、再利用の検出によりファミリーが取り消されます。
- DPoP（RFC 9449）は、アクセストークンをクライアントが保持する鍵に紐付けます。紐付けられたトークンを API で検証する方法については、[API でのトークンの検証](/docs/sdk/token-verification)を参照してください。

## セッションとサインアウト

サインインに成功すると、環境はサインインホスト上の `HttpOnly` Cookie に単一のシングルサインオンセッションを保持します。同じ環境内のアプリケーションはこれを再利用するため、ポリシーでより強力な認証や新しい認証が必要な場合を除き、2 つ目のアプリケーションでパスワードを再度求められることはありません。コードが Cookie を参照することはありません。参照するのは認可レスポンスだけです。

セッション終了エンドポイント（OpenID Connect RP-Initiated Logout 1.0）は、そのセッションを終了し、そのセッションに属するリフレッシュトークンを取り消し、バックチャネルログアウトのアドレスを登録したアプリケーションに通知します。バックエンドからユーザーのセッションを一覧表示または取り消すには、[管理 API のセッションエンドポイント](/docs/api/management/users/list-sessions)を使用してください。

ユーザーがエンタープライズ接続でサインインした場合は、セッション終了リクエストに `federated=true` を追加すると、ID プロバイダーでもサインアウトできます。ここではまずセッションが終了し、その後ブラウザーは ID プロバイダーのログアウト（SAML シングルログアウト、または OpenID プロバイダーのセッション終了エンドポイント）に移動して、`post_logout_redirect_uri` に戻ります。これは、接続で ID プロバイダーのログアウトが有効になっており、プロバイダーがログアウトのアドレスを公開している場合にのみ行われます。そうでない場合、またはプロバイダーに到達できない場合は、パラメーターなしの場合と同じように動作します。ID プロバイダーでサインアウトすると、そのプロバイダーを使用しているユーザーの他のアプリケーションも終了することがあります。
