Repository navigation
Conversation
li-xiu-qi
marked this pull request as ready for review
October 27, 2026 17:14
li-xiu-qi
requested review from
MelodyVAR,
Uking-xxx,
ZouR-Ma and
liuedcson
as code owners
October 27, 2026 17:14
li-xiu-qi
force-pushed
the
fix/239-workflow-auto-approval
branch
from
October 28, 2026 16:44
bed750d to
dd1601f
Compare
li-xiu-qi
marked this pull request as draft
October 28, 2026 16:58
li-xiu-qi
force-pushed
the
fix/239-workflow-auto-approval
branch
from
October 28, 2026 17:20
dd1601f to
e407fd2
Compare
li-xiu-qi
marked this pull request as ready for review
October 28, 2026 18:35
li-xiu-qi
marked this pull request as draft
October 28, 2026 20:29
li-xiu-qi
force-pushed
the
fix/239-workflow-auto-approval
branch
from
October 28, 2026 20:55
e407fd2 to
41c29b3
Compare
li-xiu-qi
marked this pull request as ready for review
October 28, 2026 21:04
li-xiu-qi
marked this pull request as draft
October 29, 2026 06:32
li-xiu-qi
marked this pull request as ready for review
October 29, 2026 07:43
Collaborator
Author
|
Closing this PR in favor of the systemic architectural proposal in #327. While the To maintain the long-term cleanliness and extensibility of the codebase, we believe this should be resolved at the provenance level—by distinguishing tool origins ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #239
Problem
To prevent third-party MCP servers and dynamic plugins from bypassing dangerous-command inspection by wrapping shell commands in custom tool names, the Step permission policy generically inspects tool inputs for fields named
command,cmd, orscriptand runs command-policy analysis on them.Because the permission decision entry point (
decideStepToolCall) currently receives only a baretoolName: stringand lacks origin metadata distinguishing trusted core built-in tools from untrusted third-party extensions, this defensive heuristic applies indiscriminately across all tools.That heuristic is wrong for Step's built-in
workflowtool: itsscriptfield holds JavaScript executed inside a QuickJS memory sandbox with no access to an operating-system shell, child processes, or network. Feeding multi-line JavaScript into the Bash AST parser causes the parser to report the code as unanalyzable (unresolved), which pins the workflow behind a forced confirmation under Approve for Me. Furthermore, a script that merely constructs a string mentioning a hazardous pattern (such as`rm -rf ./tmp/cache`inside a template literal) gets flagged as a dangerous command, even though no shell exists in the sandbox. These false positives interrupt unattended runs and degrade routine workflow automation.Changes
NON_SHELL_SCRIPT_TOOLS, initially containingworkflow, to identify tools whosescriptfield carries program source rather than a shell command.commandandcmdremain fully analyzable so that any future shell-invoking argument on the tool will still be inspected.bashorpowershell), which would leave custom MCP tools unmonitored, the global heuristic remains active for all other tools and arguments.then_runchained-command handling without modification.Behavior and compatibility
decideStepToolCallis exported from the package entry point. Its signature and return shape are unchanged; only the decision for one specific input shape changes.scriptPathworkflowworkflow: "deny"scriptfieldsNo migration or escape path is needed: no persisted data, prompt, default, or accepted input changes. Consumers that call
decideStepToolCalldirectly and relied onworkflow.scriptbeing read as a shell command will see a different decision, but that reading was the defect. Adding another tool whosescriptis non-shell source requires listing it inNON_SHELL_SCRIPT_TOOLSexplicitly; this PR deliberately does not infer language or safety from the field name alone.Agents started by a workflow still run their own tool-call permission checks. This change only stops treating the outer JavaScript source as a shell command.
Validation
Platform: Windows 11, Node.js 24.21.0,
pnpm@9.15.9. All commands run frompackages/coding-agent.Permission and command-policy suites, all 318 passed:
Workflow suites, all 69 passed:
Static checks, all passed:
Upstream CI on head
41c29b33:build-check-testandCheck commit attributionboth completed withconclusion: success.Defect probes, run against
test/step-permissions.test.tsto confirm the new tests actually bite:scriptexemption: 7 failed, 53 passed (60).keeps workflow.command analyzableandkeeps workflow.cmd analyzable.Intentional skip: the main describe block in
test/step-command-policy-shell-semantics.test.tsisskipIf(process.platform === "win32"), so 171 cases are skipped on Windows and were not executed locally.Limitations
NON_SHELL_SCRIPT_TOOLSis a targeted point fix forworkflow.script. BecausedecideStepToolCallcurrently operates only on tool names without origin metadata (isInternal/isBuiltinvs third-party MCP), it cannot separate trust domains natively. The systemic long-term solution is to introduce tool-origin metadata or capability manifests separating built-in tools from untrusted extensions, which requires cross-package protocol updates and will be tracked in a follow-up proposal issue.test/workflow-runtime.test.tshas one pre-existing Windows failure,a transient progress write failure does not poison later writesat line 532: the assertion expectsEISDIRorENOTDIR, while WindowsrenameraisesEPERM. The same failure reproduces on this PR's parent commit, so it is unrelated to this change and will be tracked in a separate issue.