Fail-open vs fail-closed: enabling fail-closed mode
"Fail-open" and "fail-closed" decide what happens when analysis can't finish in time — for example, if a detector errors or a downstream check times out.
- ▸Fail-open — the request is allowed through. This is the default for threat detection, so an internal fault never blocks legitimate traffic.
- ▸Fail-closed — the request is denied on any error or timeout. Safer, but a fault can block real traffic.
The detection timeout is controlled by THREAT_ANALYSIS_TIMEOUT (default 5.0s), after which detection fails open. The rare Tier-4 LLM escalation also fails open on timeout.
What is already fail-closed
Several controls deny by default when their backing store is unavailable — you don't need to change anything for these:
- ▸Rate limiting — a Redis or database error denies the request.
- ▸Token revocation checks — fail closed when Redis is down (configurable).
- ▸Tenant isolation — a request with no resolved organization sees no rows.
- ▸The metrics endpoint — closed on failure.
Turning on fail-closed enforcement
Enforcement has two switches plus per-path verification behavior:
# Block on detection instead of only flagging
THREAT_AUTO_BLOCK=true # default: false (flag-only)
# Enforcement mode for the verification middleware
ENFORCEMENT_MODE=block # monitor | block | terminate | mutateFor the Verification Engine, high-risk paths (the AI Gateway and MCP routes) already run fail-closed — bad output is blocked synchronously. Other paths are configurable per path, so you can tighten them one at a time.
Fail-closed hardening on the deepest verification stage is still being rolled out, so don't assume fully fail-closed end-to-end. Tighten path-by-path and confirm each one — see Rolling out fail-closed mode safely.