allow, block, or require_approval. Policies are matched in priority order — the first match wins.
Policy structure
Policies are stored in thepolicies table. The TypeScript shape used by the engine:
Evaluation order
Matching logic
A policy matches when all of the following are true:toolequals the request tool (or policy tool is"*")actionPatternmatches the action string (exact match or wildcard with*suffix, e.g.pull_request.*)resourceTypematches when setriskLevelmatches when set (policy risk level ≤ request risk level, based onminRiskLevel/maxRiskLevelin conditions)conditions.allowedAgentsincludes the agent ID when setconditions.blockedAgentsdoes not include the agent ID when set- For MCP:
toolNameexactly matches ortoolNamePatternmatches the MCP tool name
Risk levels
Risk levels are ordered:low < medium < high < critical.
| Level | Examples |
|---|---|
low | GET requests, read operations, list operations |
medium | Create issue, create comment, update issue, Linear issue create |
high | Create pull request, push commit, create release |
critical | Delete branch, force-push, delete repository |
- Name starts with
get,list,read→low - Name contains
delete,destroy,drop,remove→high - Everything else →
medium
Default behavior
If no policy matches, the engine returnsrequire_approval — the action is queued for a human reviewer and is not forwarded automatically. This is a safe default: agents cannot take write actions without either an explicit allow policy or human sign-off.
Exception:
repos.delete (repository deletion) is always blocked outright when no policy matches, regardless of the default behavior above. Repository deletion is treated as an unrecoverable destructive action.allow policy with actionPattern: "*" at a high priority number. To block them, add a block catch-all instead: