Cosa significano i termini
Ogni controllo che si colloca nel percorso di una request può non riuscire a produrre una risposta: una dipendenza va in timeout, manca un segnale, una chiave non può essere recuperata. Fail open significa che la request prosegue come se il controllo non ci fosse. Fail closed significa che la request prende il percorso più restrittivo: viene negata, sottoposta a challenge o inoltrata a un controllo più forte già esistente.
Nessuno dei due è corretto in assoluto. La scelta giusta dipende da cosa fa la route e da quanto costa una decisione errata.
Perché è importante per i controlli sugli actor
I controlli sugli actor aggiungono contesto alle request: se l'interazione sembra umana, assistita da AI, guidata da un agent o sconosciuta. Quando quel contesto non è disponibile, l'applicazione deve comunque rispondere. Due schemi di failure sono comuni:
- Fail closed accidentale. Un timeout o un segnale mancante viene trattato come sospetto e gli utenti reali vengono bloccati durante un disservizio.
- Fail open accidentale su azioni sensibili. Un risultato mancante viene trattato silenziosamente come umano e un'azione ad alto impatto prosegue con meno controllo del previsto.
Entrambi nascono dal lasciare implicita la scelta. La soluzione è deciderla esplicitamente, per ogni route. Il nostro articolo su come progettare policy a livello di app per umani e agent AI mostra come il comportamento in caso di failure si inserisce in una policy per route.
Come scegliere
Un approccio pratico è raggruppare le route in livelli di rischio:
- Impatto basso (pagine pubbliche, documentazione, route del catalogo in sola lettura): fail open. Un risultato actor mancante non dovrebbe cambiare nulla.
- Impatto medio (registrazioni, invio di form, ricerche con costo): di solito fail open con logging, oppure applica un'adattamento leggero come un rate limit standard.
- Impatto alto (modifiche dell'account, export di dati, azioni irreversibili): fail closed verso il tuo controllo più forte già esistente, come la riautenticazione o la conferma. Il punto non è bloccare, ma tornare al controllo che useresti comunque.
Poi definisci lo stesso comportamento per i casi correlati:
- Timeout: il controllo non ha risposto in tempo.
- Telemetria mancante: l'integrazione non è stata eseguita o un segnale era assente.
- Unknown: il controllo è stato eseguito ma l'evidenza non supportava una determinazione.
- Evidenza obsoleta: il risultato è precedente e non dovrebbe essere riutilizzato per un'azione più sensibile.
Idee sbagliate comuni
- "Fail closed è più sicuro." Sposta il costo sugli utenti legittimi. Per le route a basso impatto, un fail closed durante un incidente può fare più danni del rischio che previene.
- "Unknown è un failure." Unknown è un risultato valido. Merita una gestione esplicita propria, che può coincidere o meno con la gestione del timeout.
- "Un risultato mancante significa umano." Non inferire mai una classe di actor dall'assenza di evidenza.
Come lo gestisce Proof of Actor
Proof of Actor non assegna mai Human a un timeout o a un risultato Unknown, e installarlo non blocca nulla: i team iniziano in modalità di osservazione. Il comportamento fail open o fail closed per ciascuna route e ciascun livello di rischio è una scelta del proprietario dell'applicazione, applicata nel tuo codice tramite Route. In questo modo l'enforcement resta prevedibile e puoi verificare gli esiti prima che qualsiasi policy vada in produzione.
Leggi come si inseriscono le decisioni di routing, oppure richiedi l'accesso anticipato.