Agent Governance ToolkitAgent Governance Toolkit 4.1.0 · Python 3.10+
Dashboard
0%
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.

ExampleAn empty governor allows everything
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}")

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.

ExampleNo parameter turns the default to deny
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)

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 policyAllows everythingDenies everything
A forgotten ruleLets the call throughBlocks the call
How to get itPass nothingPass 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.
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 mode or default argument and confirm there is none.

Every expert started right here.