
# Token di accesso per la front API

Gli endpoint dell'account della front API (`/fapi/v1/me…`, `/fapi/v1/verifications…` e `/fapi/v1/organizations…`) accettano due tipi di autenticazione:

- il cookie `__Host-idp_session` dell'utente, sull'host di accesso dell'ambiente (le pagine account ospitate lo usano);
- un token di accesso per la front API, per un'applicazione first-party che gira su un'altra origine (una single-page app o un'app nativa).

## Ottenere il token

Chiedi all'endpoint dei token della front API come risorsa (RFC 8707), in uno scambio con authorization code o in un refresh:

```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
```

Il valore è l'issuer dell'ambiente seguito da `/fapi`. La richiesta viene accettata solo quando:

- l'applicazione è un'applicazione first-party attiva (altrimenti `invalid_target`);
- la richiesta include una proof DPoP (altrimenti `invalid_dpop_proof`);
- il grant appartiene a una sessione di accesso e, in caso di refresh, il refresh token è legato a DPoP (altrimenti `invalid_target`).

Cambia solo il token di accesso. La sua audience è `<issuer>/fapi`, include solo gli scope OpenID del grant (`openid`, `profile`, `email`, `phone`, `offline_access`), ha la stessa durata di un token userinfo ed è legato alla chiave della proof. Il grant stesso, il suo refresh token e i suoi scope restano invariati; un refresh ruota il refresh token come di consueto.

## Chiamare gli endpoint dell'account

Invia il token con lo schema DPoP e una nuova proof per ogni richiesta (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>` più il percorso, senza la query. `ath` è il SHA-256 in base64url del token di accesso.
- Non viene letto nessun cookie. La richiesta agisce sulla sessione per cui il token è stato emesso; se quella sessione termina, il token smette di funzionare.
- Una richiesta browser da un'altra origine deve provenire da una delle origini web consentite dell'applicazione. Le richieste cross-origin non inviano mai credenziali.
- Una modifica sensibile richiede comunque un accesso recente. La risposta `401 step_up_required` include quindi `WWW-Authenticate: DPoP error="insufficient_user_authentication", …, max_age=300`.

## Errori

| Stato | Codice | Quando |
| --- | --- | --- |
| 400 | `malformed_request` | Più di un header `Authorization`, oppure un header che non è `DPoP <token>`. |
| 401 | `unauthenticated` | Il token è non valido, scaduto o revocato, ha un'altra audience, non è legato a DPoP, oppure la sua sessione o applicazione non è più attiva. |
| 401 | `invalid_dpop_proof` | La proof non è valida oppure è stata firmata con un'altra chiave. |
| 401 | `use_dpop_nonce` | Invia una nuova proof con il nonce presente nell'header `DPoP-Nonce`. |
| 403 | `origin_not_allowed` | L'origine della pagina non è una delle origini web consentite dell'applicazione. |

Ogni `401` include una challenge `WWW-Authenticate: DPoP …`.
