Writing Rules

Veto uses a priority-based rule engine to evaluate tool calls. Rules are checked before AI scoring — a matching rule returns a decision immediately without calling the AI model.

Rule fields

FieldTypeRequiredDescription
rule_type"whitelist" or "blacklist"YesWhitelist → allow, Blacklist → deny
tool_patternstring (regex)YesRegex matched against the tool name using fullmatch
content_patternstring (regex)NoRegex matched against tool input using search
descriptionstringNoHuman-readable note shown in the dashboard
priorityintegerNo (default: 0)Higher priority rules are evaluated first
enabledbooleanNo (default: true)Disabled rules are skipped

How matching works

  1. Rules are sorted by priority descending (highest first)
  2. For each enabled rule:
    • tool_pattern is tested with re.fullmatch() — the entire tool name must match
    • If content_pattern is set, it's tested with re.search() — a substring match is enough
    • If both match, the rule fires
  3. First match wins — no further rules are evaluated
  4. If no rule matches → AI scoring (if enabled) → fail policy

Content extraction

When checking content_pattern, Veto extracts a single string from the tool input by checking these keys in order:

command → file_path → pattern → url → query → (full JSON stringified input)

For a Bash tool call, the command field is checked. For Read/Write/Edit, the file_path is checked.

Examples

Allow all read-only tools

{
  "rule_type": "whitelist",
  "tool_pattern": "Read|Glob|Grep",
  "description": "Allow all read-only tools",
  "priority": 10
}

Allow Bash but only for tests

{
  "rule_type": "whitelist",
  "tool_pattern": "Bash",
  "content_pattern": "^(npm test|pytest|uv run pytest)",
  "description": "Allow test commands",
  "priority": 20
}

Block destructive Bash commands

{
  "rule_type": "blacklist",
  "tool_pattern": "Bash",
  "content_pattern": "rm\\s+-rf|sudo|chmod\\s+777|:(){ :|:& };:",
  "description": "Block dangerous shell commands",
  "priority": 100
}

High priority ensures this is checked before any whitelist that might allow Bash.

Block writes to sensitive files

{
  "rule_type": "blacklist",
  "tool_pattern": "Write|Edit",
  "content_pattern": "\\.(env|pem|key)$|/etc/|credentials",
  "description": "Block writes to sensitive files",
  "priority": 50
}

Allow everything (escape hatch)

{
  "rule_type": "whitelist",
  "tool_pattern": ".*",
  "description": "Allow all tools (disables enforcement)",
  "priority": 0
}

Low priority so other rules take precedence.

Session whitelisting

Sometimes you need to temporarily bypass all rules for a specific Claude Code session — for example, during an urgent hotfix or a trusted pair-programming session. Session whitelisting allows exactly this.

How it works

A session whitelist is a special high-priority rule (priority 1000) that automatically allows all tool calls within a single session for a limited duration. It:

  • Applies only to the specific session — other sessions are unaffected
  • Expires automatically after the chosen duration (1h, 4h, 8h, or 24h)
  • Can be revoked manually at any time from the dashboard
  • Is logged in the audit trail like any other rule match

Creating a session whitelist

From the dashboard, go to Sessions and find the active session you want to whitelist. Click Whitelist and choose a duration:

DurationUse case
1 hourQuick hotfix or debugging session
4 hoursExtended development session
8 hoursFull workday session
24 hoursLong-running autonomous task

Under the hood

When you whitelist a session, Veto creates a rule with:

  • tool_pattern: ".*" — matches every tool
  • priority: 1000 — evaluated before all other rules
  • session_id — scoped to the target session only
  • expires_at — automatic expiration

Because it has the highest priority and matches all tools, it short-circuits the entire evaluation flow for that session. Once expired or revoked, normal rules apply again.

Revoking a whitelist

From the Sessions page, click Revoke on any whitelisted session. The whitelist is removed immediately and subsequent tool calls go through normal rule evaluation.

Evaluation flow

Tool call received
  → Check rules (priority order, first match wins)
    → Whitelist match? → ALLOW (logged as "whitelist")
    → Blacklist match? → DENY  (logged as "blacklist")
    → No match?
      → AI scoring enabled? → Call AI model → ALLOW/DENY/ASK
      → AI scoring fails?   → Apply fail policy
      → No AI scoring?      → Apply fail policy

Rule templates

When setting up Veto for the first time, you can apply a built-in template from the onboarding wizard:

Safe Defaults

Read-only tools allowed, Bash restricted to common safe commands. Good starting point for most teams.

Strict Mode

Only Read, Glob, and Grep are allowed. Everything else requires AI scoring or manual approval.

AI-Powered

Read tools and task tools allowed, plus AI scoring enabled for everything else. The AI model evaluates risk on a 0–100 scale.

Tips

  • Use high priority blacklist rules for dangerous patterns — they'll be checked first
  • Use content_pattern to scope broad tool_pattern matches
  • tool_pattern uses fullmatch: Bash matches only Bash, not BashExtra — use Bash.* for prefix matching
  • content_pattern uses search: test matches anywhere — use ^test$ for exact match
  • Rules with invalid regex patterns are silently skipped
  • You can manage rules via the dashboard UI, the API, or import/export as JSON

API

MethodEndpointDescription
GET/api/v1/rulesList all rules (ordered by priority)
POST/api/v1/rulesCreate a rule
PUT/api/v1/rules/:idUpdate a rule
DELETE/api/v1/rules/:idDelete a rule
POST/api/v1/rules/bulkBulk create/update rules
POST/api/v1/rules/simulateTest a tool call against rules without logging

All endpoints require authentication (API key or JWT).