hermes - 💡(How to fix) Fix [Feature]: Per-Tool / Per-Toolset Approval Policies

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

  • Brain-hand separation: The agent can think and decide autonomously, but high-risk operations require human confirmation
  • Safety: On shared Gateway platforms (Telegram, Discord, Slack), prevent the agent from accidentally executing destructive operations
  • Flexibility: CLI can be permissive, production servers can be strict
  • MCP safety: With MCP servers adding new tools dynamically, a default always_ask policy prevents surprise tool executions

Fix Action

Fix / Workaround

  • Terminal tool is enabled, but every shell command needs user confirmation
  • Web toolset is enabled, but web_search / browse_web require approval each time
  • write_file / patch need confirmation before modifying files
  • Different platforms need different approval granularity (CLI can be permissive, Telegram should be strict)
  • The agent should think and decide autonomously, but retain a human approval gate for high-risk operations

Code Example

approvals:
  mode: always_allow               # Global default policy
  tools:                           # Override specific tools
    terminal: always_ask           # Terminal always asks
    web_search: always_ask         # Web search always asks
    write_file: always_ask         # File writes need confirmation
  toolsets:
    web: always_ask                # All tools in web toolset need approval
    terminal: smart                # Terminal uses smart LLM-based judgment
  mcp_toolsets:
    default: always_ask            # MCP toolsets default to always_ask

---

platforms:
  telegram:
    approvals:
      mode: always_ask             # Telegram: all tools require approval
      tools:
        terminal: always_ask
  cli:
    approvals:
      mode: always_allow           # CLI: auto-allow
      tools:
        terminal: smart            # But terminal uses smart judgment

---
RAW_BUFFERClick to expand / collapse

Problem or Use Case

Problem

Currently, Hermes Agent only supports approval for dangerous shell commands (e.g., rm -rf, git reset --hard) via approvals.mode (manual / smart / off). There's no way to set approval policies on individual tools or toolsets.

This makes it impossible to implement "brain-hand separation" — where the agent (brain) decides which tool to call, but the user or host application (hand) controls whether the call is actually executed.

Common scenarios that aren't possible today:

  • Terminal tool is enabled, but every shell command needs user confirmation
  • Web toolset is enabled, but web_search / browse_web require approval each time
  • write_file / patch need confirmation before modifying files
  • Different platforms need different approval granularity (CLI can be permissive, Telegram should be strict)
  • The agent should think and decide autonomously, but retain a human approval gate for high-risk operations

Why This Matters

  • Brain-hand separation: The agent can think and decide autonomously, but high-risk operations require human confirmation
  • Safety: On shared Gateway platforms (Telegram, Discord, Slack), prevent the agent from accidentally executing destructive operations
  • Flexibility: CLI can be permissive, production servers can be strict
  • MCP safety: With MCP servers adding new tools dynamically, a default always_ask policy prevents surprise tool executions

Priority

Medium-High. This significantly improves Hermes' usability and safety in sensitive environments — production servers, team-shared bots, and any scenario where the user wants the agent's autonomy but retains a human approval gate for risky operations.

Proposed Solution

Expected Behavior

Provide configurable approval policies per tool and per toolset.

Option A: Config-Driven

approvals:
  mode: always_allow               # Global default policy
  tools:                           # Override specific tools
    terminal: always_ask           # Terminal always asks
    web_search: always_ask         # Web search always asks
    write_file: always_ask         # File writes need confirmation
  toolsets:
    web: always_ask                # All tools in web toolset need approval
    terminal: smart                # Terminal uses smart LLM-based judgment
  mcp_toolsets:
    default: always_ask            # MCP toolsets default to always_ask

Option B: Event-Driven (Brain-Hand Separation)

Insert an approval check in handle_function_call() before executing any tool:

  1. Check configured policy for the tool/toolset
  2. If approval is needed, emit a tool.approval_requested event (with tool_use_id, tool name, arguments)
  3. Wait for the user or host app to respond with tool.approval_response (with result: allow|deny and optional deny_message)
  4. If denied, return "[Tool call denied: {deny_message}]" to the agent
  5. If allowed, execute normally

On Gateway platforms, send approval requests through the existing messaging channel (reusing the /approve / /deny flow).

Option C: Platform-Level Overrides

platforms:
  telegram:
    approvals:
      mode: always_ask             # Telegram: all tools require approval
      tools:
        terminal: always_ask
  cli:
    approvals:
      mode: always_allow           # CLI: auto-allow
      tools:
        terminal: smart            # But terminal uses smart judgment

Policy Modes

ModeBehaviorDescription
always_allowExecute automatically, no confirmationAuto-approve
always_askPause session, wait for user approvalAlways prompt
smartUse auxiliary LLM to judge risk; auto-allow low-risk, prompt on high-riskSmart judgment
denyBlock tool usage entirelyDisabled

Implementation Sketch

  1. Config layer: Add tools / toolsets / mcp_toolsets fields under approvals in config.yaml, with default_config.permission_policy support
  2. Check layer: Insert approval check logic in model_tools.py's handle_function_call() before tool execution
  3. Resolution order: tools.<tool_name>toolsets.<toolset_name> → global approvals.mode
  4. Event layer: Emit events when approval is needed; wait for user response via Gateway or CLI
  5. MCP support: MCP tools default to always_ask — new MCP server tools don't auto-execute without approval
  6. Custom tools: Not covered by policy — plugin/tool owner decides (same as today's custom tool pattern)

Alternatives Considered

No response

Feature Type

Gateway / messaging improvement

Scope

None

Contribution

  • I'd like to implement this myself and submit a PR

Debug Report (optional)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING