Policy¶
zeroth.governance.policy ¶
Policy and capability enforcement primitives.
This package lets you define what agents are and aren't allowed to do.
It provides models for capabilities (like network access or file writes),
policy definitions that allow or deny those capabilities, and a guard that
checks policies before a node runs. The Capability enum itself is
authored graph vocabulary defined in :mod:zeroth.contracts.graph.models
and republished here.
CapabilityDeniedError ¶
Bases: PermissionError
Raised when an operation requires capabilities the node was not granted.
Subclasses :class:PermissionError so callers that already treat tool /
memory failures as recoverable (feeding the error back to the model) keep
working, while capability denials remain distinguishable by type.
PolicyGuard ¶
PolicyGuard(
*,
policy_registry: PolicyRegistry | None = None,
capability_registry: CapabilityRegistry | None = None,
)
Checks whether a node is allowed to execute, given the active policies.
Before a node runs, the guard collects all policies from the graph and the node, then compares the node's required capabilities against what those policies allow or deny. The result is an EnforcementResult that says "allow" or "deny" (with a reason).
evaluate ¶
evaluate(
graph: Graph,
node: Node,
run: object,
input_payload: Mapping[str, Any],
) -> EnforcementResult
Decide whether a node is allowed to run under the current policies.
Gathers policies from both the graph and the node, resolves the node's required capabilities, and returns an EnforcementResult indicating ALLOW or DENY along with the effective capabilities and constraints.
evaluate_run_admission ¶
Evaluate only the policies explicitly bound to a run request.
RunAdmissionRequest ¶
Bases: Protocol
Structural contract consumed by run admission policy evaluation.
Capability ¶
Bases: StrEnum
A specific permission that a node might need to do its job.
Each value represents one kind of action (like reading from the network
or writing to the filesystem). Authored tool bindings declare the
capabilities they require, and policies use these values to control
what nodes are allowed to do; the policy engine republishes the enum
from :mod:zeroth.governance.policy.models.
EnforcementResult ¶
Bases: BaseModel
The result of checking policies before a node runs.
Contains the decision (allow/deny), an optional reason if denied, and the effective set of capabilities and constraints that apply to the node's execution.
PolicyDecision ¶
Bases: StrEnum
The outcome of a policy evaluation: either allow or deny.
PolicyDefinition ¶
Bases: BaseModel
A named set of rules that controls what capabilities are allowed or denied.
You create one of these to describe what a particular policy permits. For example, a "read-only" policy might allow NETWORK_READ but deny NETWORK_WRITE. It can also control which secrets are visible and how strict the sandbox should be.
RunAdmissionResult ¶
Bases: BaseModel
Policy-only result for admitting a run-creating request.
CapabilityRegistry ¶
A lookup table that maps short string refs to Capability values.
Use this to register capabilities by name so that graphs and nodes can reference them without importing the Capability enum directly.
PolicyRegistry ¶
A lookup table that maps policy IDs to full PolicyDefinition objects.
Register policies here so the PolicyGuard can find them when it evaluates a graph or node.
parse_effective_capabilities ¶
Read the effective (granted) capability set out of an enforcement context.
The orchestrator stores the policy guard's effective_capabilities on the
run as a JSON list of capability value strings and threads it back through
enforcement_context. This turns that list into a set[Capability].
Unmapped strings (values that do not correspond to a known
:class:Capability) are dropped: an unrecognized grant can never satisfy
a known required capability, so dropping it keeps the result fail-closed
(it grants nothing) without raising on forward-compatible extra values.
Returns an empty set when the context is missing, has no
effective_capabilities key, or lists nothing. Emptiness here means
"nothing granted" (deny everything that needs a capability) — it does NOT
mean "skip enforcement". The decision to skip is the caller's, signalled by
passing None instead of calling this helper.
require_capabilities ¶
require_capabilities(
required: Iterable[Capability],
effective: set[Capability] | None,
*,
node_id: str,
) -> None
Assert that effective covers every capability in required.
Fail-closed: effective of None is treated as the empty set, so any
non-empty required denies. When required is empty the call is a
no-op (an operation that needs no capability is always allowed).
Raises :class:CapabilityDeniedError listing the missing capabilities.
apply_secret_policy ¶
apply_secret_policy(
env: Mapping[str, str],
*,
allowed_secrets: list[str],
secret_access_enabled: bool,
) -> dict[str, str]
Filter environment variables so only policy-approved secrets get through.
Returns a dictionary containing only the env vars whose names appear in
allowed_secrets. If secret access is disabled or no secrets are
allowed, returns an empty dictionary.
default_capability_registry ¶
Build a CapabilityRegistry that resolves every capability by its value.
Each :class:Capability is registered under its own string value (e.g.
"memory_read" -> Capability.MEMORY_READ). This is the ref scheme the
served path expects: graphs declare capability_bindings=["memory_read",
...] and the wired-in :class:PolicyGuard resolves them without any
app-specific registration. Apps that use a bespoke ref scheme (e.g.
"capability://memory-read") build and inject their own registry instead.