Policies and rules¶
OpenAgentLock policy is deterministic YAML. No LLM lives inside the evaluator. A rule (called a gate in the YAML schema) is a path-shape match plus a verdict. Verdicts are allow, deny, or skip — there is no ask verdict in the default path, and the schema rejects it at load time.
Most operators do not author policies from scratch. The shape of a real-world policy is:
- The five built-in defaults the daemon boots with — useful baseline, intentionally narrow.
- A handful of community rules pulled from openagentlock/rules on top.
- Optionally, a private rules registry with internal-to-your-org rules.
This page covers all three plus the YAML schema underneath them.
Two switches: mode and rule actions¶
Two things determine whether a tool call is blocked:
- Top-level
modeat the root of your policy file:monitororenforce. Withoutmode: enforce, every matched rule is downgraded toallowregardless of evaluator output. - Per-rule action (
on_hit,on_miss).
PATCH /v1/mode toggles the daemon-level switch, which is the outer override. In firewall mode it escalates any policy-monitor match back to deny; in monitor mode it suppresses any policy deny to allow. Use it as the global kill switch — per-rule mode: monitor remains the right tool for staging individual rules during rollout.
The community rules registry — start here¶
The openagentlock/rules registry hosts ready-to-install gates the community has tested in the wild. Browse the catalog at https://openagentlock.github.io/rules/, copy the install one-liner, and paste:
# Upstream is auto-registered on first sync.
agentlock rules sync
# Search the catalog by name, tag, or description.
agentlock rules search exfil
agentlock rules search bash
# Install — the rule's gate block is POSTed to the daemon's
# /v1/policy/gates/yaml endpoint and lands in the live policy with a
# fresh hash. Existing sessions stay pinned to the old hash until they
# reload, so installs never invalidate in-flight work.
agentlock rules install exfil.curl-with-env
agentlock rules install rogue.secret-read
# Remove later — by gate id, the same /v1/policy/gates/{id} DELETE
# handler the dashboard uses.
agentlock rules uninstall exfil.curl-with-env
agentlock rules is wired through to the same daemon endpoint the local web dashboard uses, so installs are immediately visible at http://127.0.0.1:7879/rules.
Pin a private registry too¶
Most teams want a few internal-only rules alongside the upstream catalog. Any Git repo with the same rules/<id>/rule.yaml layout works:
# Tap your private registry. Multiple registries are merged at sync time.
agentlock rules add https://github.com/your-org/your-rules.git
# Confirm what's wired up.
agentlock rules sources
# Remove a registry (local-only — does not touch installed gates).
agentlock rules remove your-org-your-rules
If a rule id collides between two registries the CLI errors out and asks you to disambiguate with <registry-id>:<rule-id>. The same rule.yaml schema applies to both registries; the registry's own CI validates against schema/rule.schema.json on every PR.
Authoring new rules with an agent¶
When the catalog doesn't have what you need, the openagentlock/skills toolkit ships agent skills (Claude Code, Cursor, Codex) that turn natural-language intent into a rule.yaml and run agentlock rules install to land it. See the block-pattern skill for the canonical "block this command shape" flow.
The five built-in defaults¶
When the daemon boots, it loads policies/default.yaml, which ships these five gates in monitor mode. They are intentionally narrow — most operators leave them on and add registry rules on top.
Package install¶
supply-chain.pkg-install
pip install, npm install, brew install, cargo install. Catches typosquats and build-time exfiltration.
Untrusted MCP¶
supply-chain.untrusted-mcp
MCP server with an unpinned public key. Fingerprints land in /v1/mcp/pin.
Secret reads¶
rogue.secret-read
Reads of .env, ~/.ssh, ~/.aws/credentials, anywhere a secret-shaped path appears in the command.
The community registry has tighter / opinionated variants of several of these — e.g. rogue.git-force-push (only deny force-push to main / develop / release), exfil.curl-with-env (catch the $ENV_VAR exfil shape specifically), rogue.eval-untrusted (deny dynamic-eval shells). Install whichever match your threat model.
Authoring rules from scratch¶
Two rules of thumb:
Match on path shape, not on reader name. A rule like
(cat|head|grep)\s+.*\.envis bypassable by the agent pickingsed,awk,xxd, orpython. Prefer(\.env(\b|[._-])|/\.ssh(/|\b)|/\.aws(/|\b)|credentials)— the secret-shaped path token alone, anywhere in the command.Use the dashboard. The local web dashboard (
127.0.0.1:7879) lets you right-click a logged tool call and "block this next time" — it generates a starter rule from the call's shape. Iterate from there.
Authoring via the dashboard¶
Open http://127.0.0.1:7879/. The dashboard is shaped like a firewall admin UI:
- Log table — every tool call across every harness, filterable by source/session/verdict
- Rule tree — visual editor for the YAML policy
- Live activity — SSE feed; new entries stream in
Changes are validated against the policy schema before being written, and a snapshot of the previous policy is saved so you can revert.
Policy schema¶
The full schema lives in api/openapi.yaml under components.schemas.Policy. Community-rule authors should match the registry shape documented in schema/rule.schema.json. Minimal example:
version: 1
mode: monitor
defaults:
bash: allow
gates:
- id: rogue.secret-read
match:
tool: Bash
any_command_regex:
- '(\.env(\b|[._-])|/\.ssh(/|\b)|/\.aws(/|\b)|credentials)'
evaluate:
- kind: always
action: deny
The daemon's regex engine is Go RE2 — no negative lookahead, no backreferences. If you find yourself reaching for (?!…), invert the match: write a positive regex for the dangerous shape rather than a negative regex around the safe one.
Nudges¶
Each evaluate[] clause may carry an optional nudge: <string> hint. When the clause fires a deny, the harness shim splices the hint onto the reason it forwards to the model as "<reason>\n\n→ Suggested: <nudge>". Use it to redirect the agent toward a safer command (e.g. trash instead of rm) or to point at the right skill instead of leaving it to retry blindly.
Nudges only surface on deny verdicts; allow, monitor-suppressed, and non-matching paths drop the field. See the openagentlock/rules registry for safety.rm-suggest-trash and safety.secret-read-suggest-skill as canonical examples.
Enforcement vs monitor¶
- Monitor — every gate matches but the verdict is downgraded to
allowfor the harness. Use this on day one. - Enforce — the verdict is honored. Switch on per-gate first if you want to ramp gradually; the schema permits a
modefield on individual rules to override the global setting.