Re-introduces the per-tool approval system from luzidd's commit 39124f3 (which is no longer reachable from main) and improves it before re-landing. What's restored: - ApprovalPolicy (allow/deny/prompt) plus DEFAULT_APPROVAL_POLICIES. - ACTION_EXCEPTIONS registry (LSP read-only, bash critical patterns). - getApprovalPolicy() six-level resolution order. - ExtensionToolWrapper.execute() gate before extension handlers. - --auto-approve / --yolo CLI flag and tools.approval.<tool> user config. - docs/approval-mode.md user guide. What's improved over the original: - Replaced unchecked 'as any' casts with typed unknown narrowing helpers. - Validate userConfig values: invalid strings, numbers, etc. fall through to the built-in default instead of being silently honoured (typo no longer locks a tool out or grants implicit approval). - Expanded CRITICAL_BASH_PATTERNS: chmod -R /, chown -R /, bash <(curl ...), writes to /etc/passwd|shadow|sudoers, shutdown/reboot/halt/init 0, kill -9 1, nc -e / nc -c reverse shells. Pattern shapes require a command-position boundary so 'npm run reboot-tests' and 'echo "shutdown the queue"' don't false-positive. - Added DEBUG_READONLY_ACTIONS exception so DAP inspection actions (threads, stack_trace, variables, scopes, read_memory, …) auto-allow while execution-side actions (launch, attach, continue, evaluate, write_memory, set_breakpoint, …) still prompt. - formatApprovalPrompt: labels mcp__<server>__<tool> calls as MCP server tools, surfaces ssh host + command, recognises the modern § hashline header for edit, and truncates >240-char fields so a heredoc-sized body cannot blow out the confirmation dialog. - Test suite grown from 40 to 57 cases — new coverage for invalid user config, the extended critical-bash patterns, benign-keyword negatives, debug exceptions, MCP/ssh prompt formatting, and command truncation. Verification: - bun test packages/coding-agent/test/tools/approval.test.ts -> 57 pass - bun x biome check . -> clean - bun run check:ts across all 9 workspaces -> clean
5.4 KiB
Tool Approval Policies
Per-tool approval policies allow fine-grained control over which tools require user confirmation before execution.
Overview
By default:
- Read-only tools (read, find, search, ast_grep, web_search) are auto-allowed
- Destructive tools (bash, write, edit, ast_edit, debug, browser, eval) require approval
- External/custom tools (MCP, extensions) require approval
- LSP tool requires approval by default, but read-only actions (
diagnostics,definition,references,hover,symbols, …) are auto-allowed - Debug tool requires approval by default, but inspection actions (
threads,stack_trace,variables,scopes,read_memory, …) are auto-allowed - Critical bash patterns always prompt, even if bash is allowlisted (safety override)
Action-Based Exceptions
Some tools have action-based exceptions that apply policy based on specific inputs:
LSP Tool (performance optimization):
- Default policy:
prompt - Exception: read-only actions → auto-allowed
- Result:
diagnostics,hover,referencesdon't prompt;rename,code_actionsdo prompt
Bash Tool (safety override):
- Default policy:
prompt - Exception: critical patterns → force prompt (overrides user config)
- Result:
rm -rf /,sudo rm, fork bombs always prompt, even withbash: allow
Quick Start
Bypass all approvals for automation
omp --auto-approve -p "Fix all TypeScript errors"
omp --yolo -p "Refactor the auth module"
Configure per-tool policies
Add to ~/.omp/agent/config.yml or .omp/config.yml:
tools:
approval:
bash: allow # Never prompt for bash
write: prompt # Always prompt for write (default)
edit: allow # Never prompt for edit
custom-tool: deny # Block a custom tool entirely
Configuration
Policy Values
allow— Auto-approve (never prompt)deny— Block the tool entirely (throws error)prompt— Require user confirmation (default for destructive tools)
Resolution Order
- Overriding action exceptions (safety rules; user config cannot bypass).
- User config for the specific tool (
tools.approval.<toolName>), validated — invalid values fall through. - Non-overriding action exceptions (performance optimizations).
- Built-in default for the tool (see
DEFAULT_APPROVAL_POLICIES). - User-supplied
_default(only consulted for tools with no built-in default — MCP/custom). - System-wide fallback (
prompt).
Critical Pattern Override
Dangerous bash patterns always prompt, regardless of policy:
rm -rf /
sudo rm -rf
:(){ :|:& };:
chmod -R 777 /
These patterns force confirmation even if tools.approval.bash: allow is set.
Non-Interactive Mode
When approval is required but no UI is available (e.g., RPC mode, --mode json), the tool throws:
Tool "bash" requires approval but no interactive UI available.
Options:
1. Use --auto-approve flag
2. Add to config: tools.approval.bash: allow
Automated Workflows
For CI/CD or scripted workflows, use --auto-approve:
# GitHub Actions
omp --auto-approve --no-session -p "Run tests and fix linting"
# Cron job
omp --yolo -p "Update dependencies and commit"
Security Considerations
- Trust your prompts:
--auto-approvebypasses all safety checks - Review allowlists: Regularly audit
tools.approvalconfig - Critical patterns: Cannot be disabled (this is intentional)
- External tools: Require approval by default (no built-in allowlist)
Examples
Allow bash and write for local development
# .omp/config.yml (project-local)
tools:
approval:
bash: allow
write: allow
Deny browser tool in shared environments
# ~/.omp/agent/config.yml (user-global)
tools:
approval:
browser: deny
Selective automation
# Auto-approve for known-safe operations
omp --auto-approve --tools read,find,grep -p "Analyze codebase"
# Manual approval for destructive changes
omp -p "Refactor authentication module"
Migration from Extensions
If you previously used a custom extension for approval (e.g., confirm-destructive.ts), you can:
- Remove the extension — built-in approval supersedes it
- Migrate allowlists — convert extension config to
tools.approval.* - Test behavior — verify prompts appear as expected
Example migration:
// Old extension: ~/.omp/agent/extensions/confirm-destructive.ts
const ALLOWED_TOOLS = ["read", "find", "search"];
// New config: ~/.omp/agent/config.yml
tools:
approval:
bash: prompt
write: prompt
edit: prompt
# read/find/search already auto-allowed by default
Troubleshooting
"Tool requires approval but no UI available"
Problem: Running in non-interactive mode (RPC, JSON, headless)
Solution:
- Add
--auto-approveflag, or - Set
tools.approval.<tool>: allowin config
Prompts appear for read-only tools
Problem: Custom or MCP tools may not be recognized as read-only
Solution:
tools:
approval:
custom-readonly-tool: allow
Critical pattern bypass attempt
Problem: rm -rf / prompts even though bash is allowlisted
Behavior: This is intentional. Critical patterns cannot be auto-approved.
See Also
- Configuration Reference
- Custom Tools
- Extensions
- GitHub Issue #1030