STEERPLANE

Policy Engine

Hierarchical deny, allow, rate-limit, and approval rules evaluated before execution.

The policy engine decides whether an action is allowed to run — before any LLM call or tool invocation happens. Rules are evaluated in a strict priority order.

Evaluation order

Deny list — highest priority

If the action matches any deny pattern, it is blocked immediately, before cost is incurred.

Allow list

If an allow list is configured, the action must match at least one pattern, or it is blocked.

Rate limits

Sliding-window counters per pattern; actions exceeding the configured rate are blocked.

Approval gate — lowest priority

Matching actions require human approval via a registered callback before they proceed.

Configuration

from steerplane import PolicyEngine, RateLimitSpec

policy = PolicyEngine(
    denied_actions=["delete_*", "drop_*", "sudo_*"],
    allowed_actions=["search_*", "read_*", "summarize"],
    rate_limits=[RateLimitSpec(pattern="send_email", max_count=5, window_seconds=60)],
    require_approval=["refund_*", "wire_transfer"],
    approval_callback=my_approval_fn,
)

decision = policy.check("delete_users")
# raises PolicyViolationError(rule="deny:delete_*")

Matching uses POSIX glob patterns (fnmatch), so delete_* blocks delete_users, delete_db, and so on — deterministically, with no model in the loop.

A policy violation always hard-terminates the run — it is a non-overridable safety invariant, independent of the enforcement mode.

Typical pattern

@guard(
    agent_name="ops_agent",
    denied_actions=["delete_*", "drop_*"],   # destructive → blocked
    # rate limits & approvals configured via PolicyEngine or .steerplane.yml
)
def run():
    agent.run()

On this page