Team
When something is down
Enforcement happens on the machine, in the sandbox, from the last policy it accepted. Nothing in our cloud is in that path. When a piece is missing, Fenzi either keeps the last good state or refuses to start. An enrolled machine never falls back to something wider on its own. A developer who signs out returns their machine to Free, and the console sees that machine stop reporting.
What happens when
| If this is unavailable | Running sandboxes | New sandboxes |
|---|---|---|
| Our control plane | Keep enforcing the policy they loaded. | Start from the last signed policy the machine verified. run and status say the control plane is unreachable and name the revision in use. |
| Our control plane, on a machine that never received a policy | None are running. | Refused. An enrolled machine does not fall back to the Free default. |
| A valid signature | Unaffected. | A bundle that fails the signature check, or is older than the one held, is ignored and reported. The machine keeps the revision it had. |
| The policy prover | Unaffected. | Refused. run exits with code 2 unless the result is within_boundary. |
| The sandbox runtime | Whatever the runtime does. Fenzi does not enforce anything itself. | Refused. run exits with code 3 and doctor says what is missing. |
| The network, entirely | Keep denying what they denied before. The model call fails too, so the agent stops being useful. | Start, if the image is already built and the policy is cached. |
A revision the sandbox cannot load
If a running sandbox receives a policy revision it cannot load, the runtime's own setting decides what happens:
fail_closed, the default, blocks network traffic until a valid revision loads.retain_last_validkeeps enforcing the last revision that loaded.
Both keep the sandbox inside its rules. fenzi doctor reports which one the gateway uses. Fenzi does not change it.
Decisions and requests
- Decision records wait on the machine and upload when the control plane answers. If the local queue fills, the forwarder says how many were dropped.
- Requests for more access stay pending. The blocked call stays blocked. In the console, no approval happens without a reviewer. An answer given on the machine still works, and the console shows it as drift once the machine reports again.
- A review made in the console before the outage is applied on the forwarder's next pass after it.
A gateway restart
The runtime keeps a limited buffer of recent events and loses it when the gateway restarts. Decisions in that buffer that were not forwarded yet are gone. The forwarder notices, starts reading from the current position, and sends a gap record, so the console shows the span it is missing. On Free, the saved log for that sandbox holds what arrived before the restart.
On Free
On Free, nothing in enforcement depends on us. It needs the runtime, the prover, and an image builder on the machine, and nothing else. The only call to fenzi.dev is the update check, at most once a day, which you can turn off; see The update check.
Test it yourself
Start an agent with
fenzi run claudeon an enrolled machine.Block the control plane's address on that machine.
Ask the agent to fetch a host the policy does not list.
fenzi log --denyshows the deny.Run
fenzi status. It names the cached revision and says the control plane is unreachable.Unblock it and run
fenzi forward --once. The deny reaches the console.