Skip to content

Commit db19e0b

Browse files
authored
Merge pull request #32 from kevinnft/fix/run-command-permission-gate
fix(security): require user permission before run_command executes
2 parents b04728a + 90aaa12 commit db19e0b

4 files changed

Lines changed: 28 additions & 2 deletions

File tree

src-tauri/src/agents/runner.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,27 @@ impl AgentRunner {
10341034
executor: &ToolExecutor,
10351035
tool_call: &ParsedToolCall,
10361036
) -> Option<oneshot::Receiver<bool>> {
1037+
if tool_call.name == "run_command" {
1038+
let command = tool_call
1039+
.input
1040+
.get("command")
1041+
.and_then(Value::as_str)
1042+
.map(std::string::ToString::to_string)?;
1043+
1044+
let rx = self.permissions.register(agent_run_id.to_string());
1045+
1046+
let _ = self.app_handle.emit(
1047+
"agent-permission-request",
1048+
AgentPermissionRequestEvent {
1049+
agent_run_id: agent_run_id.to_string(),
1050+
permission_type: "shell_command".to_string(),
1051+
path: command,
1052+
agent_type: agent_type.to_string(),
1053+
},
1054+
);
1055+
return Some(rx);
1056+
}
1057+
10371058
let path = tool_call
10381059
.input
10391060
.get("path")

src/components/chat/PermissionDialog.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ export function PermissionDialog({ request, onAllow, onDeny }: PermissionDialogP
3131
Agent <span className="font-semibold text-[var(--text)]">{agentLabel}</span> wants to access a path outside the project:
3232
</>
3333
)}
34+
{request.type === 'shell_command' && (
35+
<>
36+
Agent <span className="font-semibold text-[var(--text)]">{agentLabel}</span> wants to run a shell command:
37+
</>
38+
)}
3439
<br />
3540
<span className="inline-block mt-2 font-mono text-xs bg-[var(--surface-2)] px-2 py-1 rounded border border-[var(--border)] break-all">
3641
{request.path}

src/components/layout/AppShell.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ export const AppShell: React.FC = () => {
310310

311311
const unlistenPermission = await listen<{
312312
agentRunId: string;
313-
type: 'sensitive_file' | 'outside_sandbox';
313+
type: 'sensitive_file' | 'outside_sandbox' | 'shell_command';
314314
path: string;
315315
agentType: string;
316316
}>('agent-permission-request', (event) => {

src/types/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ export interface AgentRunWithTools extends AgentRun {
127127
}
128128

129129
export interface PermissionRequest {
130-
type: 'sensitive_file' | 'outside_sandbox';
130+
type: 'sensitive_file' | 'outside_sandbox' | 'shell_command';
131131
path: string;
132132
agentType: AgentType;
133133
agentRunId: string;

0 commit comments

Comments
 (0)