fix(security): deny unapproved tool calls on non-CLI channels (#998)

When autonomy is set to "supervised", the approval gate only prompted
interactively on CLI. On Telegram and other channels, all tool calls
were silently auto-approved with ApprovalResponse::Yes, including
high-risk tools like shell — completely bypassing supervised mode.

On non-CLI channels where interactive prompting is not possible, deny
tool calls that require approval instead of auto-approving. Users can
expand the auto_approve list in config to explicitly allow specific
tools on non-interactive channels.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Edvard Schøyen 2026-02-20 05:22:56 -05:00 committed by GitHub
parent 9fdc4c36b1
commit 861137b2b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1099,11 +1099,13 @@ pub(crate) async fn run_tool_call_loop(
arguments: call.arguments.clone(), arguments: call.arguments.clone(),
}; };
// Only prompt interactively on CLI; auto-approve on other channels. // On CLI, prompt interactively. On other channels where
// interactive approval is not possible, deny the call to
// respect the supervised autonomy setting.
let decision = if channel_name == "cli" { let decision = if channel_name == "cli" {
mgr.prompt_cli(&request) mgr.prompt_cli(&request)
} else { } else {
ApprovalResponse::Yes ApprovalResponse::No
}; };
mgr.record_decision(&call.name, &call.arguments, decision, channel_name); mgr.record_decision(&call.name, &call.arguments, decision, channel_name);