Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 75 additions & 41 deletions docs/guide/policies.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Policies and the five gates
# Policies and rules

OpenAgentLock policy is **deterministic YAML**. No LLM lives inside the evaluator. A rule 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.
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:

1. The **five built-in defaults** the daemon boots with — useful baseline, intentionally narrow.
2. A handful of **community rules** pulled from [openagentlock/rules](https://openagentlock.github.io/rules/) on top.
3. 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

Expand All @@ -11,9 +19,56 @@ Two things determine whether a tool call is blocked:

`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 five baseline gates
## The community rules registry — start here

The [openagentlock/rules](https://github.com/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:

```bash
# 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](dashboard.md) 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:

```bash
# 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`](https://github.com/openagentlock/rules/blob/main/schema/rule.schema.json) on every PR.

Every install ships `policies/default.yaml` with five gates in monitor mode:
### Authoring new rules with an agent

When the catalog doesn't have what you need, the [openagentlock/skills](https://github.com/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.

<div class="gate-grid" markdown>

Expand Down Expand Up @@ -54,40 +109,16 @@ Reads of `.env`, `~/.ssh`, `~/.aws/credentials`, anywhere a secret-shaped path a

</div>

## Authoring rules
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+.*\.env` is bypassable by the agent picking `sed`, `awk`, `xxd`, or `python`. 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.

## Installing community rules

The [openagentlock/rules](https://github.com/openagentlock/rules) registry ships ready-to-pin gates. Browse them at <https://openagentlock.github.io/rules>, then install via CLI:

```bash
# upstream is auto-registered on first sync
agentlock rules sync
agentlock rules search exfil

# install one rule into the live policy
agentlock rules install exfil.curl-with-env

# remove later
agentlock rules uninstall exfil.curl-with-env
```

The rule's `gate:` block is POSTed to `/v1/policy/gates/yaml` 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.

You can register additional registries (private internal rules, etc.):

```bash
agentlock rules add https://github.com/your-org/your-rules.git
agentlock rules sources
agentlock rules remove your-org-your-rules # local-only — does not touch installed gates
```

## Authoring via the dashboard

Open <http://127.0.0.1:7879/>. The dashboard is shaped like a firewall admin UI:
Expand All @@ -100,23 +131,26 @@ Changes are validated against the policy schema before being written, and a snap

## Policy schema

The full schema lives in [`api/openapi.yaml`](https://github.com/openagentlock/OpenAgentLock/blob/main/control-plane/api/openapi.yaml) under `components.schemas.Policy`. Minimal example:
The full schema lives in [`api/openapi.yaml`](https://github.com/openagentlock/OpenAgentLock/blob/main/control-plane/api/openapi.yaml) under `components.schemas.Policy`. Community-rule authors should match the registry shape documented in [`schema/rule.schema.json`](https://github.com/openagentlock/rules/blob/main/schema/rule.schema.json). Minimal example:

```yaml
version: 1
mode: monitor

evaluator:
on_miss: allow
on_hit: deny

defaults:
bash: allow
gates:
- id: rogue.secret-read
when:
command_regex: '(\.env(\b|[._-])|/\.ssh(/|\b)|/\.aws(/|\b)|credentials)'
on_hit: deny
severity: high
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.

## Enforcement vs monitor

- **Monitor** — every gate matches but the verdict is downgraded to `allow` for the harness. Use this on day one.
Expand Down
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ nav:
- Guide:
- Getting started: guide/getting-started.md
- Installation: guide/installation.md
- Policies and the five gates: guide/policies.md
- Policies and rules: guide/policies.md
- Signers: guide/signers.md
- The ledger: guide/ledger.md
- Local web dashboard: guide/dashboard.md
Expand Down
Loading