fix(security): deny tool calls requiring approval on remote channels
Remote channels (Telegram, Discord, Slack, etc.) previously either auto-approved tool calls requiring approval (in the else-branch) or bypassed the approval check entirely (by passing None for the ApprovalManager). Both paths allowed unapproved tool execution. This fix: - Wires ApprovalManager into ChannelRuntimeContext so remote channels actually enter the approval check - Changes the non-CLI branch from auto-approve to deny-by-default - Adds a tracing::warn log and descriptive error message guiding users to configure auto_approve or set autonomy level to Full - Updates stale doc comment on prompt_cli Co-authored-by: xj <gh-xj@users.noreply.github.com>
This commit is contained in:
parent
276c470c1f
commit
470af7051c
@ -1308,6 +1308,8 @@ pub(crate) 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() {
|
||||
@ -1338,13 +1340,26 @@ pub(crate) 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),
|
||||
|
||||
@ -581,8 +581,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)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user