An external authorization service needs a deliberate answer for uncertainty.
In my Cloudflare Access training evaluator, only one known state grants access:
training_status == completed
Everything else denies:
completed → allow
started → deny
not started → deny
user missing → deny
lookup error → deny
invalid claim → deny
That is a fail-closed design.
The important lesson is not that every external evaluator must always fail closed. Availability requirements can differ. The lesson is that the failure mode should be a conscious policy choice rather than the accidental result of exception handling.
For a sensitive application, I would rather be able to state precisely what happens when the external control is unavailable than discover it during an outage.
Related: Enforcing Security Training with Cloudflare Access External Evaluation.