Write a policy
A policy is the list of what your agents may and may not do. You set the limits once, and Scopebond applies them to every checked action before it runs.
There are two ways to set one:
- Coding agents: change the limits with short commands. You never write policy files by hand.
- Your own agent, MCP servers, frameworks or GitHub checks: write a short JSON policy.
Coding agents: change the limits
See the current limits in plain English, change one, then preview a decision without running anything:
npx @scopebond/hook@latest rules # show the limits
npx @scopebond/hook@latest rules block terraform # add a program to the risky list
npx @scopebond/hook@latest rules allow dd # take one off it
npx @scopebond/hook@latest rules protect infra/ # add a folder the agent must not write
npx @scopebond/hook@latest rules protect-branch production # add a branch the agent must not push to
npx @scopebond/hook@latest rules enforce safe-shell # make that rule block, not just record
npx @scopebond/hook@latest test "terraform apply" # preview a decision
unprotect and unprotect-branch undo a protection. Changes apply to the next action.
Every rule starts by recording what it would have stopped, without blocking it. rules enforce <rule> makes one rule block (protect-branches, safe-shell, protect-write or protect-read); rules monitor <rule> puts it back to recording. Scopebond's own protection always blocks.
Changes need a person at a terminal, or --yes in a script. The agent cannot loosen its own limits: the hook denies it if it tries to set up, trust, remove or reconnect Scopebond.
The limits live in .scopebond/rules.json. If you edit that file by hand, run npx @scopebond/hook@latest rules apply afterwards.
Your own agent: write a JSON policy
1. Start from the starter file
npx @scopebond/gateway@latest init writes scopebond.policy.json.
2. Add a clause for each thing the agent may do
A clause names the action types it covers and their limits. Anything outside every clause is denied. Write a clear description: Scopebond shows it when it blocks an action.
{ "id": "fs", "type": "action_allowlist", "mode": "enforce",
"description": "Filesystem tools only, no deletes or writes",
"action_types": ["mcp.tool.call"],
"param_bounds": { "server": { "enum": ["filesystem"] }, "tool": { "pattern": "^(?!delete_|write_).+" } } }
Other clause types cover spending limits, allowed web endpoints and rate limits. See the Policy reference.
3. Pick a mode for each clause
| Mode | What happens | Use it for |
|---|---|---|
enforce (default) | Blocks the action before it runs | Anything you can block safely |
require_approval | Holds the action until a named approver signs, or denies it at the timeout | Rare, high-value actions |
monitor | Lets the action run, then flags it | Only limits that cannot be checked in real time, such as totals across several gateways |
4. Load it
Start the gateway with the file. It refuses to start on an invalid policy. While it runs, it reloads the file when you save. A broken edit is rejected and the last valid policy stays in force.
Review rules as a team
In the workspace, Rules shows recommended rules for each kind of agent. A second person approves your own drafts before export. The workspace never blocks anything itself. Blocking stays in your hook or gateway.
What a policy does not do: scan content or classify data. Rules are about actions and their parameters. If a control cannot be written that way, keep it in the tool that owns the data.