Skip to content

Detect operator's active shell instead of assuming Bash #964

Description

@Aaronontheweb

Summary

Netclaw's approval gate, hard-deny rules, safe-verb list, and verb-chain extraction all assume a POSIX shell — specifically Bash, via BashParser from ShellSyntaxTree. The daemon doesn't check what shell the operator is actually using; it just hands every shell_execute call through the Bash-shaped pipeline. On Windows, on a pwsh-default operator's machine, or in a container that uses dash/ash/fish, this produces silent mismatches:

  • The parser may parse a PowerShell or fish command as if it were Bash, succeed, and run the wrong shell-quoting/redirection semantics under the hood.
  • The hard-deny rules and safe-verb list are POSIX-shaped (rm -rf /, dd, :(){:|:&};:) and miss equivalents in other shells (Remove-Item, Get-ChildItem | Remove-Item -Recurse -Force, etc.).
  • The verb-chain extraction treats Invoke-Expression, &, |, and ; differently from how PowerShell actually evaluates them.

What we should detect

At daemon startup (or on first shell_execute per session), determine:

  1. Operator's preferred shell — read $SHELL on POSIX, COMSPEC/parent process on Windows, or fall back to platform default (bash on Linux/macOS, pwsh on Windows when present, cmd otherwise).
  2. Whether the agent is actually running through that shellShellTool currently spawns bash -c (or equivalent); if we change it to honor the detected shell, the parser/gate need to change too.

The detection result becomes part of ToolExecutionContext or a new ShellEnvironment service consumed by ShellTool, ShellCommandPolicy, and ToolAccessPolicy.

Why now

Blocks #SHELL-POWERSHELL — we can't ship a PowerShell-aware approval gate until we can tell which shell to apply. Also closes a real failure mode for Windows operators today: the daemon currently assumes Bash on every platform.

Out of scope

  • The PowerShell-specific parser, hard-deny rules, and safe-verb list — separate issue.
  • Multi-shell support per session (e.g., shell_execute accepting a Shell arg). Probably YAGNI; one shell per operator session is enough.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecuritySecurity-related changes

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions