
# Esegui un passaggio di accesso

`POST /fapi/v1/transactions/current/steps/{step}` · chiamato dall'host di accesso dell'ambiente

Esegue un passaggio della transazione corrente. Questa versione accetta i passaggi `identifier` e `password`. Ogni passaggio di credenziali non riuscito restituisce lo stesso `401 invalid_credentials`, quindi la risposta non rivela mai se un account esiste. Quando il passaggio della password completa la transazione, vengono impostati i cookie di sessione `__Host-idp_session` (e, quando serve, `__Host-idp_device`) e il cookie di transazione viene rimosso.

## Richiesta

Intestazioni:

| Intestazione | Obbligatoria | Descrizione |
| --- | --- | --- |
| `Idp-Client` | sì | Identificatore dell'SDK. |
| `Origin` | sì | Deve essere esattamente `https://<sign-in host>`. |
| `Idp-Csrf-Token` | sì | Il `csrf_token` dell'oggetto transazione. |

Percorso: `step`, il nome del passaggio (`identifier`, `password`, `sso_start`).

Al passaggio `otp_send`, `next_steps[].methods` elenca i metodi senza password che la policy effettiva consente (`email_otp`, `magic_link`); un client offre solo questi.

Corpo (i campi dipendono dal passaggio; `next_steps[].fields` li elenca):

| Campo | Tipo | Descrizione |
| --- | --- | --- |
| `identifier` | stringa | Indirizzo email, numero di telefono o nome utente (passaggio `identifier`), fino a 320 caratteri. |
| `password` | stringa | La password (passaggio `password`), fino a 128 caratteri. |
| `connection_id` | stringa | Un valore `sso_connections[].connection_id` (passaggio `sso_start`). |

## Risposta

`200 OK` con la transazione dopo il passaggio. Una transazione `completed` non ha `csrf_token`.

Quando l'ambiente richiede un secondo fattore e l'utente non ne ha ancora nessuno, un utente che è ancora nel periodo di tolleranza dell'ambiente `mfa.enrollment_grace_days` accede comunque e la risposta `completed` contiene `mfa_enrollment`: `required_by` (RFC 3339, la fine della tolleranza, calcolata dal server) e `methods` (`webauthn`, `totp`: i fattori che l'utente può registrare ora, nell'ordine delle schermate). Mostra la data e lascia che l'utente continui; la registrazione si aggiunge nelle impostazioni dell'account. Il campo è assente quando non c'è tolleranza, l'utente rispetta la policy o la registrazione è richiesta subito. Il `min_acr` di un'applicazione e il `acr_values` richiesto non vengono mai rinviati dalla tolleranza.

## Single Sign-On aziendale (home realm discovery)

Quando il passaggio `identifier` riceve un indirizzo email il cui dominio appartiene a una connessione aziendale, l'accesso prosegue con quella connessione. Solo la parte dopo `@` viene usata per la discovery.

- Una connessione: la transazione passa a `federated_redirect` e la risposta contiene `redirect_url`, l'indirizzo di avvio del provider di identità. Naviga alla finestra di primo livello verso quell'indirizzo. L'indirizzo contiene un token monouso: non memorizzarlo né registrarlo.
- Più connessioni: la transazione resta in `identifier_pending` e la risposta elenca `sso_connections` (`connection_id`, `display_name`, `protocol`). Mostra `display_name` come testo e invia la scelta dell'utente con il passaggio `sso_start` (`identifier` e `connection_id`). Una connessione non offerta per il dominio restituisce `422 validation_failed`.
- Nessuna connessione, oppure discovery temporaneamente non disponibile: l'accesso normale prosegue, così un'interruzione non blocca gli altri metodi di accesso. `sso_start` è una scelta esplicita e restituisce invece `503 temporarily_unavailable`.

Quando la richiesta di accesso indica un'organizzazione che richiede SSO, la transazione offre solo le connessioni di quell'organizzazione: i passaggi con password e con codice email non sono offerti, e la passkey resta disponibile solo se l'organizzazione ha account di emergenza (break-glass). La creazione della transazione avvia già l'unica connessione (`federated_redirect` con `redirect_url`) oppure elenca più connessioni in `sso_connections`; invia la scelta con `sso_start` e `connection_id` soltanto, `identifier` è facoltativo qui. Con questo requisito la discovery non ripiega su altri metodi: quando l'accesso aziendale non è raggiungibile, il passaggio restituisce `503 temporarily_unavailable`. Lo stesso vale quando il dominio email appartiene a un'organizzazione che richiede SSO per i suoi domini verificati.

Dopo il provider di identità, il browser torna a `/u/sso/complete` sull'host di accesso; la pagina ospitata completa l'accesso.

## Collegare l'accesso aziendale a un account esistente

Quando una connessione aziendale non garantisce gli indirizzi email e l'indirizzo che dichiara è già verificato su un account dell'ambiente, l'accesso aziendale non apre una sessione. Il browser torna alla pagina di accesso ospitata con una nuova transazione il cui oggetto contiene `account_link`: `connection_name` e, quando la connessione appartiene a un'organizzazione, `organization_name`. Comunica all'utente che ha già un account e che deve accedervi per collegare la connessione; non nominare mai l'account. In questa transazione `sso_start` e `magic_link` non sono offerti, e il passaggio `identifier` non instrada verso una connessione aziendale.

L'utente accede all'account esistente con i propri metodi; un utente con un secondo fattore registrato viene invitato a usarlo. Il passaggio che completa la transazione non apre alcuna sessione: la connessione viene collegata all'account, e la risposta è una nuova transazione in `federated_redirect` con `redirect_url` per la stessa connessione. Naviga alla finestra di primo livello verso quell'indirizzo; l'accesso aziendale ora termina come di consueto. Se l'accesso aziendale non può essere avviato, la nuova transazione è `identifier_pending` e segue un accesso ordinario.

Completare con un altro account, senza il secondo fattore registrato, o con un accesso più vecchio della richiesta di collegamento non collega nulla e non apre alcuna sessione: `409 transaction_state_conflict`. Una richiesta di collegamento scaduta (10 minuti) o già usata restituisce `410 transaction_expired`. Una richiesta di collegamento si usa una sola volta, qualunque sia l'esito. Per rifiutare, chiama `POST /fapi/v1/transactions/current:cancel`.

## Policy dell'organizzazione

Quando la richiesta di autorizzazione è vincolata a un'organizzazione, la policy di accesso dell'organizzazione viene verificata di nuovo dopo il primo fattore e subito prima dell'apertura della sessione:

- L'indirizzo IP del client non è nella allowlist dell'organizzazione: `403 ip_not_allowed`.
- I fattori della transazione non soddisfano la policy dell'organizzazione (un metodo che l'organizzazione non consente, un fattore mancante, oppure una chiave di sicurezza o passkey fuori dalla allowlist AAGUID dell'organizzazione): `403 no_allowed_method`.
- La policy dell'organizzazione non può essere letta: `503 temporarily_unavailable`. L'accesso fallisce in modo sicuro e non prosegue mai senza la policy.

Nessuna sessione viene aperta. Un rifiuto al completamento della transazione rimuove il cookie di transazione; un `503` dopo il primo fattore lascia la transazione dov'era, e il passaggio può essere ripetuto. Il corpo dell'errore non nomina mai l'organizzazione, l'utente o l'indirizzo IP.

## Transazioni headless vincolate a DPoP

Per una transazione avviata con un'intestazione `DPoP`, invia una nuova prova dalla stessa chiave (`htm` `POST`, `htu` l'URL del passaggio) invece di `Idp-Csrf-Token`; nessun cookie viene usato. Il passaggio che completa la transazione restituisce `authorization_response` una sola volta:

```json
{
  "state": "completed",
  "authorization_response": { "code": "<code>", "state": "<your state>", "iss": "https://example.keenauth.app" },
  "next_steps": [],
  "schema_version": 1,
  "expires_at": "2026-11-02T10:15:00Z"
}
```

Verifica che `state` e `iss` corrispondano, poi scambia il codice presso `/oauth2/token` con il tuo `code_verifier` e una prova DPoP dalla stessa chiave. Una prova di un'altra chiave restituisce `invalid_grant`. Se la richiesta di autorizzazione non può terminare con un codice (serve consenso, termini legali, una scelta dell'organizzazione o un nuovo accesso, oppure l'accesso è negato), il passaggio restituisce `403 authorization_failed` e il membro `error` contiene il codice di errore OAuth; nessun codice viene emesso.

## Errori

| Stato | Codice | Quando |
| --- | --- | --- |
| 401 | `invalid_credentials` | L'identificatore o la password non sono accettati. |
| 403 | `origin_not_allowed` | `Origin` o `Idp-Csrf-Token` manca o è errato. |
| 403 | `ip_not_allowed` | L'indirizzo IP del client non è nella allowlist dell'organizzazione. |
| 403 | `no_allowed_method` | L'accesso non rispetta la policy dell'organizzazione. |
| 403 | `test_feature_not_in_production` | `otp_verify` o `email_2fa` ha ricevuto il codice di test fisso `424242` in un ambiente di produzione. Il tentativo viene conteggiato come un codice errato. |
| 404 | `not_found` | Il nome del passaggio non è un passaggio noto. |
| 409 | `transaction_state_conflict` | Il passaggio non è disponibile nello stato corrente. |
| 409 | `session_limit_reached` | L'utente ha raggiunto il limite di sessioni e le nuove sessioni sono negate. |
| 410 | `transaction_expired` | La transazione è terminata. |
| 422 | `validation_failed` | Un campo manca o non è valido. |
| 503 | `temporarily_unavailable` | `sso_start` non ha potuto raggiungere l'accesso aziendale, oppure la policy dell'organizzazione non può essere letta; riprova. |
| 401 | `invalid_dpop_proof` | La prova `DPoP` manca, non è valida o è già stata usata. |
| 403 | `authorization_failed` | La transazione vincolata a DPoP è stata completata, ma la sua richiesta di autorizzazione è terminata senza codice. |

## Esempio

```bash
curl -X POST https://example.keenauth.app/fapi/v1/transactions/current/steps/identifier \
  -H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
  -H "Origin: https://example.keenauth.app" \
  -H "Idp-Csrf-Token: $CSRF_TOKEN" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"identifier":"jane@example.com"}'
```

## Dati personali

Questo endpoint contiene dati personali: profilo dell'utente finale e credenziali. [Dati personali nelle API di KeenAuth](/docs/policies/personal-data) descrive cosa viene memorizzato, per quanto tempo viene conservato e come viene cancellato. Non inviare categorie particolari di dati personali (salute, dati biometrici, religione, opinioni politiche, orientamento sessuale) in nessun campo.
