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_redirecte la risposta contieneredirect_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_pendinge la risposta elencasso_connections(connection_id,display_name,protocol). Mostradisplay_namecome testo e invia la scelta dell'utente con il passaggiosso_start(identifiereconnection_id). Una connessione non offerta per il dominio restituisce422 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 invece503 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:
{
"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
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 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.