security
Intended Documentation
Fail-Closed Controls
Understand the fail-closed security model — how Intended behaves when services are unavailable, how defaults work, and circuit breaker behavior.
Fail-Closed Controls#
Intended operates on a fail-closed principle: when any component in the verification chain is unavailable or returns an ambiguous result, the system denies the request. No AI execution proceeds without an explicit, verified allow decision.
Fail-Closed vs. Fail-Open#
Most systems default to fail-open — if the authorization service is down, requests pass through. This prioritizes availability over security.
Intended takes the opposite approach:
| Scenario | Fail-Open (typical) | Fail-Closed (Intended) |
|---|---|---|
| Policy engine unreachable | Allow | Deny |
| Decision token expired | Allow with warning | Deny |
| Evaluation timeout | Allow with degraded logging | Deny |
| Unknown action type | Allow (no matching deny rule) | Deny |
Info
The fail-closed model means availability depends on the health of the verification chain. This is an intentional trade-off — Intended prioritizes security correctness over uptime of downstream AI services.
What Triggers a Fail-Closed Response#
The system returns a deny decision with a fail_closed reason code in the following scenarios:
Policy engine unavailable#
If the policy engine cannot be reached within the configured timeout (default: 3 seconds), the request is denied.
Evaluation timeout#
If policy evaluation exceeds the maximum duration (default: 5 seconds), the in-progress evaluation is abandoned and the request is denied.
Token signing failure#
If the decision token cannot be signed (key unavailable, HSM timeout), the evaluation result is discarded and the request is denied.
Enforcement point cannot verify#
If the enforcement point cannot validate a decision token (signature verification failure, clock skew beyond tolerance), the request is denied even if the token payload contains an "allow" result.
Circuit Breaker Behavior#
Intended implements a circuit breaker pattern to prevent cascading failures when a component is persistently unavailable.
Closed state (normal)
Requests flow through the authorization chain normally. Each failure increments a failure counter. The circuit breaker monitors the failure rate over a rolling 60-second window.
Open state (tripped)
When the failure rate exceeds the threshold (default: 50% of requests over 30 seconds), the circuit breaker trips. All subsequent requests receive an immediate deny response without attempting to reach the failing component. This reduces load on the recovering service.
Half-open state (probing)
After the cooldown period (default: 15 seconds), the circuit breaker allows a single probe request through. If the probe succeeds, the circuit breaker returns to the closed state. If the probe fails, it returns to the open state.
Circuit Breaker Configuration#
Circuit breaker thresholds are configurable per tenant:
Warning
Setting failure_threshold_percent too high delays circuit breaker activation, causing request pile-ups. Setting it too low triggers false positives during normal latency spikes. The default of 50% is appropriate for most deployments.
Default Deny Semantics#
Intended uses default-deny semantics at every layer:
- No matching policy — deny. Unlike permissive systems, the absence of a rule is not an implicit allow.
- Ambiguous evaluation — deny. If the policy engine produces a result that is neither explicit allow nor explicit deny, the system treats it as deny.
- Conflicting policies — deny. If multiple policies produce conflicting results for the same intent, deny takes precedence.
The Deny Hierarchy#
When multiple deny reasons apply, Intended reports the most specific one:
- Explicit policy deny (a rule actively denied the request)
- Fail-closed deny (a system component was unavailable)
- Default deny (no matching allow rule)
The deny hierarchy ensures that audit logs reflect the true reason for denial, which is critical for debugging and compliance.
Monitoring Fail-Closed Events#
Fail-closed events emit structured metrics and audit records. Key metrics to monitor:
| Metric | Description |
|---|---|
meritt.authorization.fail_closed.total | Total fail-closed denials |
meritt.authorization.fail_closed.by_reason | Denials broken down by reason code |
meritt.circuit_breaker.state | Current state of each circuit breaker |
meritt.circuit_breaker.trips | Number of times the circuit breaker has tripped |
Alerting Recommendations#
- Alert on
fail_closed.totalexceeding baseline by 2x within 5 minutes - Alert immediately on
circuit_breaker.statetransitioning toopen - Alert on sustained
half_openstate lasting longer than 60 seconds
Overriding Fail-Closed (Emergency Access)#
Danger
Intended does not provide a global fail-open override. This is by design. An override mechanism would become the target of every attack against the system.
For emergency scenarios, operators can:
- Deploy a permissive policy — create and activate a broad-allow policy through the standard policy pipeline. This is audited and reversible.
- Bypass at the connector level — individual connectors can be configured with a static allow list for specific actions. This requires operator-level access and produces a security audit event.
- Scale the failing component — address the root cause rather than bypassing authorization.
Related Resources#
- Enforcement Lineage — tracing decisions through the authorization chain
- Operational Readiness — verify fail-closed behavior before going live
- Trust Model — the security model that fail-closed controls enforce