> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ctrlrun.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Fail closed

> Fail closed means anything CTRLRun cannot decide is denied: an unknown action, a missing or malformed policy, a missing or expired principal, a missing.

Fail closed means that anything CTRLRun cannot decide, it denies. An unknown action, a missing
policy, a malformed policy, a missing or expired principal, a missing, expired, consumed or
mismatched approval, a template that cannot be resolved, a store whose schema it does not
recognise: all refused, before the executor runs. There is no flag that makes a consequential
action permissive by default, in the kernel, in `verify`, or in an adapter.

## The table

| Condition                                                             | Result                                                       | Where              |
| --------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------ |
| Action name not in the policy                                         | `ActionDenied`, reason `unknown_action`                      | policy             |
| No `ctrlrun.yaml`, or one that does not parse or validate             | `PolicyError`; no `Control` is built                         | load               |
| No principal, or one whose credential has expired                     | `ActionDenied`, reason `no_principal` or `principal_expired` | before authority   |
| `authority:` present and no grant matches                             | `AuthorityDenied`                                            | before policy      |
| `approve` decided and no approval presented                           | `ApprovalRequired`                                           | before reservation |
| Approval presented for a different hash, already consumed, or expired | `ApprovalMismatch`                                           | consumption        |
| Effect key held by another in-progress or committed attempt           | `DuplicateEffect`                                            | reservation        |
| Effect key `AMBIGUOUS`                                                | `AmbiguousEffect`                                            | reservation        |
| Store schema newer than the binary understands                        | `SchemaMismatch`                                             | open               |
| Any exception from the executor other than `NotExecuted`              | `AMBIGUOUS`, never `FAILED`                                  | outcome            |

Each is an exception of its own, raised as itself so an agent loop can tell them apart, and
each writes a refused receipt and an event naming the reason.

## Why it is not configurable

A flag that relaxed one of these would be set in exactly the deployment where it mattered, and
the receipts from that deployment would say the guard was on. The same rule binds `ctrlrun
verify`, which has no argument that makes its `Control` behave differently from yours, and every
adapter, which ships no `auto_approve`, no `dry_run` and no development mode that grants.
Observe mode is the one way to run unprotected on purpose, and it says so on every receipt.

## The guarantee it supports

Fail closed: G6 (unknown action refused) and G7 (no principal refused) in `ctrlrun verify`, and
every row above has an acceptance test.

## What it does not do

Failing closed is about what CTRLRun decides. It cannot refuse a call that bypasses the decorator
entirely, a compromised host, or an executor that raises `NotExecuted` after the remote acted;
those are in the threat model as limits, not as vulnerabilities.

## Next

* [Decisions](/concepts/decisions): the three that can be reached.
* [Errors reference](/reference/errors): every exception and when it is raised.
* [Threat model](/THREAT_MODEL) · [Get started](/get-started/quickstart) · [Why](/why).


## Related topics

- [Roll out observe, then enforce](/guides/observe-to-enforce.md)
- [CTRLRun and guardrail libraries](/compare/guardrail-libraries.md)
- [Observe mode](/concepts/observe-mode.md)
- [Errors](/reference/errors.md)
- [Threat model](/THREAT_MODEL.md)
