
# フロント API アクセストークン

フロント API のアカウント関連エンドポイント（`/fapi/v1/me…`、`/fapi/v1/verifications…`、`/fapi/v1/organizations…`）は、次の 2 種類の認証を受け付けます。

- 環境のサインインホストで使われるユーザーの `__Host-idp_session` Cookie（ホスト型のアカウントページがこれを使用します）。
- 別のオリジンで動作するファーストパーティのアプリケーション（シングルページアプリまたはネイティブアプリ）向けのフロント API アクセストークン。

## トークンの取得

認証コードの交換またはリフレッシュの際に、リソースとしてフロント API を指定して（RFC 8707）、トークンエンドポイントにリクエストします。

```http
POST /oauth2/token
Content-Type: application/x-www-form-urlencoded
DPoP: <proof>

grant_type=refresh_token&refresh_token=<refresh token>&client_id=app_01j9...&resource=https%3A%2F%2Facme.keenauth.app%2Ffapi
```

値は、環境の発行者に `/fapi` を付けたものです。次の条件をすべて満たす場合にのみリクエストが受理されます。

- アプリケーションが有効なファーストパーティのアプリケーションであること（そうでない場合は `invalid_target`）。
- リクエストに DPoP プルーフが含まれていること（そうでない場合は `invalid_dpop_proof`）。
- 付与がサインインセッションに紐づいていること。リフレッシュの場合は、リフレッシュトークンが DPoP にバインドされていること（そうでない場合は `invalid_target`）。

変わるのはアクセストークンのみです。そのオーディエンスは `<issuer>/fapi` であり、付与された OpenID スコープ（`openid`、`profile`、`email`、`phone`、`offline_access`）のみを含みます。有効期間はユーザー情報トークンと同じで、プルーフの鍵にバインドされます。付与自体、そのリフレッシュトークン、スコープはそのまま維持されます。リフレッシュ時には、通常どおりリフレッシュトークンがローテーションされます。

## アカウントエンドポイントの呼び出し

DPoP スキームでトークンを送信し、リクエストごとに新しいプルーフを付与します（RFC 9449）。

```http
GET /fapi/v1/me/sessions
Idp-Client: <SDK identifier>
Authorization: DPoP <access token>
DPoP: <proof with htm, htu, iat, jti, ath>
```

- `htu` は `https://<sign-in host>` にパスを加えたもので、クエリは含めません。`ath` はアクセストークンの base64url エンコードされた SHA-256 ハッシュです。
- Cookie は読み取られません。リクエストは、そのトークンが発行されたセッションに対して処理されます。そのセッションが終了すると、トークンは使えなくなります。
- 別のオリジンからのブラウザリクエストは、アプリケーションに許可されたウェブオリジンのいずれかから送られている必要があります。クロスオリジンのリクエストが認証情報を伴うことはありません。
- 機密性の高い変更には、引き続き直近のサインインが必要です。その場合、`401 step_up_required` の応答には `WWW-Authenticate: DPoP error="insufficient_user_authentication", …, max_age=300` が含まれます。

## エラー

| ステータス | コード | 発生条件 |
| --- | --- | --- |
| 400 | `malformed_request` | `Authorization` ヘッダーが複数ある、または `DPoP <token>` の形式ではない場合。 |
| 401 | `unauthenticated` | トークンが無効、期限切れ、または取り消し済みである場合、別のオーディエンス向けである場合、DPoP にバインドされていない場合、またはそのセッションやアプリケーションが有効でなくなっている場合。 |
| 401 | `invalid_dpop_proof` | プルーフが無効である場合、または別の鍵で署名されている場合。 |
| 401 | `use_dpop_nonce` | `DPoP-Nonce` ヘッダーの nonce を使って、新しいプルーフを送信してください。 |
| 403 | `origin_not_allowed` | ページのオリジンが、アプリケーションに許可されたウェブオリジンのいずれでもない場合。 |

すべての `401` には `WWW-Authenticate: DPoP …` のチャレンジが含まれます。
