Skip to content

bash permission "Always allow" never matches commands with leading environment variable assignments #52720

Closed as not planned

Description

@graphenn

Description

Description

For bash commands prefixed with environment variable assignments (e.g. FOO=1 cmd ...), choosing "Always allow" in the permission prompt saves a pattern that can never match the command, so the same kind of command keeps asking forever.

Version

1.18.34 (also present on current dev: packages/opencode/src/tool/shell.ts collect + packages/opencode/src/permission/arity.ts).

Reproduction

  1. Configure an ask rule that matches the full command, e.g.:

    { "permission": { "bash": { "*": "allow", "*FOO=1*": "ask" } } }
  2. Run FOO=1 true, choose Always allow.

  3. Run FOO=1 echo hello.

Expected: step 3 is allowed without a prompt (covered by the saved always pattern).

Actual: step 3 asks again, and every subsequent FOO=1 ... command asks again.

Root cause

ShellTool.collect builds two different sets:

  • patterns (the string checked against permission rules) = full command text, e.g. FOO=1 true.
  • always (the grant saved by "Always allow") = BashArity.prefix(tokens).join(" ") + " *", where tokens comes from parts(node).

parts(node) only collects command_name / command_name_expr / word / string / raw_string / concatenation, so the leading variable_assignment (FOO=1) is dropped. BashArity.prefix then falls back to the first token (true), producing the grant true *.

Permission matching uses anchored globs (Wildcard.match builds ^<pattern>$), so true * never matches the checked pattern FOO=1 true.

Unprefixed commands are unaffected (e.g. Always on head -60 yields head *, which does match).

Suggested fix

Keep leading variable assignments when deriving the always pattern (e.g. include variable_assignment in the token list used by parts, giving FOO=1 true *), or strip them from the pattern used for matching. Add a regression test asserting the always pattern derived from FOO=1 git status matches the permission pattern of FOO=1 git commit.

Plugins

No response

OpenCode version

1.18.34

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. github-actions commented on Oct 2, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues covering inline environment-variable prefixes in bash permission matching. The reported failure modes differ, but the underlying permission parsing behavior is closely related. Please check:

    • #14110: Bash permission rules do not match commands with environment-variable prefixes.
    • #16075: Inline environment-variable prefixes can affect bash permission-rule matching.
  2. graphenn commented on Oct 2, 2026

    @graphenn
    Author

    Not a duplicate of #14110 / #16075 — those describe the opposite failure mode.

    Both referenced issues were auto-closed for inactivity, not fixed.

    A unified fix should normalize leading assignments consistently on both sides: either strip them from the pattern used for matching (which would also fix #14110/#16075), or keep them in both patterns and always. Regression tests should cover both directions: rule matching for FOO=1 git commit, and always-grant matching after an allowed FOO=1 git commit.

  3. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the detailed report and root-cause analysis!

    This was reported against 1.18.34, which is OpenCode v1. v1 only gets fixes for critical bugs (data loss, security problems, or crashes/breakage with no workaround). Here the result is extra permission prompts, and you can work around it with an explicit rule in your config, for example:

    { "permission": { "bash": { "FOO=1 *": "allow" } } }

    So this is unlikely to be fixed in v1.

    One note: the files you mention (packages/opencode/src/tool/shell.ts, packages/opencode/src/permission/arity.ts) are v1 code and aren't on the current dev branch. v2 (@opencode/cli, the opencode command) is a separate implementation with its own shell permission handling. We'd encourage upgrading to v2. If you can reproduce this on v2, or think it's more serious than it looks, please reply here with the v2 version and steps and we'll take another look.

  4. opencodejr commented on Oct 29, 2026

    @opencodejr

    Closing this as not planned. The bug is in v1 (1.18.34), and v1 only gets fixes for critical bugs. This one causes extra permission prompts, and an explicit allow rule like "FOO=1 *": "allow" works around it. We haven't heard that it also happens on v2.

    Thanks again for the detailed analysis! If you can reproduce this on v2 (@opencode/cli), please open a new issue with the v2 version and steps, and link back here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions