Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion crates/forge-llm/src/cli_adapters/claude_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ impl ClaudeCodeAgentProvider {
.arg(prompt)
.arg("--output-format")
.arg("stream-json")
.arg("--verbose");
.arg("--verbose")
// The spawned session has stdin=null so it cannot answer
// permission prompts. Without this flag every tool call gets
// silently denied and the stage degenerates into "partial_success
// with N tool errors" without actually doing work.
.arg("--dangerously-skip-permissions");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

Bypassing all permission prompts with --dangerously-skip-permissions is a significant security risk, as it allows the LLM to execute potentially destructive tools (such as shell commands or file writes) without human oversight. While this is necessary for non-interactive execution when stdin is null, it should ideally be an opt-in configuration. Consider adding a field to AgentRunOptions to allow users to explicitly enable this behavior, or at least ensure this security trade-off is prominently documented for users of this provider.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0cd4fa3. Made it opt-in: added auto_approve_tools: bool to AgentRunOptions (defaults to false). ClaudeCodeAgentProvider only passes --dangerously-skip-permissions when that flag is true. The forge-attractor AgentProviderSubmitter (used by pipeline runs where stdin=null is the design) sets it to true; library consumers wiring up AgentProvider directly now have to make an explicit choice. Doc comment on the field explains the trade-off.


let model = options
.model_override
Expand Down