Merge pull request #2288 from zeroclaw-labs/pr-2049-mainfix

fix(security): deny approval-required tools on non-CLI channels
This commit is contained in:
Argenis 2026-03-05 01:53:03 -05:00 committed by GitHub
commit e160922872
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 3 deletions

View File

@ -2148,6 +2148,8 @@ pub async fn run_tool_call_loop(
arguments: tool_args.clone(),
};
// Only prompt interactively on CLI; deny on other channels
// (remote channels cannot provide interactive approval).
let decision = if channel_name == "cli" {
mgr.prompt_cli(&request)
} else if let Some(ctx) = non_cli_approval_context.as_ref() {
@ -2178,13 +2180,26 @@ pub async fn run_tool_call_loop(
)
.await
} else {
tracing::warn!(
tool = %tool_name,
channel = %channel_name,
"Tool requires approval but channel cannot prompt — denied"
);
ApprovalResponse::No
};
mgr.record_decision(&tool_name, &tool_args, decision, channel_name);
if decision == ApprovalResponse::No {
let denied = "Denied by user.".to_string();
let denied = if channel_name == "cli" {
"Denied by user.".to_string()
} else {
format!(
"Tool '{}' requires approval but channel '{}' cannot prompt interactively. \
Configure auto_approve or set autonomy level to Full to allow.",
tool_name, channel_name
)
};
runtime_trace::record_event(
"tool_call_result",
Some(channel_name),

View File

@ -636,8 +636,9 @@ impl ApprovalManager {
/// Prompt the user on the CLI and return their decision.
///
/// For non-CLI channels, returns `Yes` automatically (interactive
/// approval is only supported on CLI for now).
/// Only valid for the CLI channel. Non-CLI channels should not call
/// this method; the caller in `run_tool_call_loop` denies by default
/// when the channel cannot provide interactive approval.
pub fn prompt_cli(&self, request: &ApprovalRequest) -> ApprovalResponse {
prompt_cli_interactive(request)
}