1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
47 small wins to finish your pathNext lesson →
Governance is opt-in: the fail-open default
Fail-open is the toolkit's default: a governor with no policy loaded allows every action, so governance only begins once you write a rule.
Last updated: 14 Oct, 2026 · Agent Governance Toolkit 4.1.0
The govern() lesson blocked a tool with an allow-list. This lesson removes the list and shows what an empty governor does, because the answer decides how you have to deploy it.
Evaluating with no policy
A governor built with no arguments has nothing to allow or deny against. Every action, including a dangerous one, comes back allowed.
open_gate = govern() # no allow-list, no denies, no content rules
for action in ["refund", "delete_account", "wire_transfer"]:
d = open_gate.evaluate(action)
print(f"{action:16} allowed={d.allowed} {d.reason!r}")Output
refund allowed=True 'Allowed by policy' delete_account allowed=True 'Allowed by policy' wire_transfer allowed=True 'Allowed by policy'
There is no strict switch
Some gates default to deny and let you opt into allow. This one does not. The reason Allowed by policy is printed even though there is no policy, and govern() has no strict parameter to flip the default.
import inspect
from agent_os.lite import govern
# the signature has no strict / default_deny switch to turn fail-open off
params = list(inspect.signature(govern).parameters)
print(params)
print("has strict:", "strict" in params)Output
['allow', 'deny', 'deny_patterns', 'blocked_content', 'escalate', 'max_calls', 'log'] has strict: False
What fail-open means for you
- An unconfigured gate protects nothing. Forgetting to pass a policy is not an error; it silently allows every call.
- You get default-deny by writing an allow-list. With
allow=[...], anything off the list is refused, which is the next lesson's pattern. - Deny still beats allow within a policy. An action on both lists is denied. The fail-open part is only about the empty default.
Fail-open vs fail-closed
| Fail-open (this default) | Fail-closed (an allow-list) | |
|---|---|---|
| Empty policy | Allows everything | Denies everything |
| A forgotten rule | Lets the call through | Blocks the call |
| How to get it | Pass nothing | Pass allow=[...] |
Where fail-open bites
- A review of any deployment, to confirm a real policy is loaded and the gate is not empty.
- A test that fails when the policy is missing, so an empty gate never ships.
- A staged rollout, where you knowingly start permissive and tighten to an allow-list.
Watch out. A gate that is present but empty looks governed and is not. Always assert that your allow-list is non-empty before trusting the gate, and treat a missing policy as a failure, not a default.
Related
- Previous: govern(): the smallest real gate
- Next: What installing gives you
- See also: Allow-lists and default deny
Try it yourself
- Give the empty governor one deny,
govern(deny=["wire_transfer"]), and confirm everything else still passes. - Evaluate an action with
govern(allow=[])and read whether an empty allow-list denies or allows. - Search the signature for a
modeordefaultargument and confirm there is none.
Every expert started right here.