CLI: prefix_rule matching fails for shell wrappers and env-prefix commands
What version of Codex CLI is running?
codex-cli 0.106.0
What subscription do you have?
Pro
Which model were you using?
gpt-5.3-codex high
What platform is your computer?
MacOS Darwin 24.x arm64
What terminal emulator and version are you using (if applicable)?
Terminal.app (also reproducible in iTerm2)
What issue are you seeing?
Approval rules (prefix_rule) do not consistently apply when command execution is shell-wrapped (/bin/zsh -lc or /bin/bash -lc) or when a command uses leading environment assignments.
Two related failure modes:
- Existing prefix rules for the underlying command do not match if the executed command is seen as a shell wrapper script instead of normalized inner commands.
- Commands with env-prefix style invocation (for example
GH_TOKEN=... gh ...) are treated as starting with the assignment token, so rules forghdo not match.
Result: Codex repeatedly asks for approval and proposes/stores overly specific rules like full /bin/zsh -lc '...' scripts, which are brittle and do not generalize.
What steps can reproduce the bug?
- Add this rule:
prefix_rule(pattern=["gh", "api"], decision="allow")
- Model executes a shell-wrapped command with redirection/connector (representative form):
/bin/zsh -lc 'gh api repos/openai/codex/issues/1 > /tmp/issue.json && jq ".number" /tmp/issue.json'
- Observe approval is requested even though
gh apiis allow-listed. - Choose “Yes, and don't ask again…”.
- Observe saved rule is often wrapper/script specific (for example full
/bin/zsh -lc '...') rather than a stable command prefix. - Repeat with a small command variation (different output path/flags) and observe approval prompts again.
- Env-prefix variant: run
GH_TOKEN=dummy gh api userwith the same["gh", "api"]allow rule; observe prompt instead of a match.
What is the expected behavior?
Policy evaluation and suggested amendments should use a normalized command representation:
- Shell wrappers should be unwrapped to the actionable inner command(s) when safely parseable.
- Leading env assignments (
KEY=VALUE) prefixes should not prevent matching command-prefix rules. - Approval rule suggestions should prefer stable/minimal prefixes (for example
["gh", "api"]) instead of full shell wrapper scripts. - When parsing is ambiguous/unsafe, fallback should remain conservative (prompt) and avoid incorrect broad approvals.
Additional information
Potential implementation plan (codebase points):
- Normalize command tokens for exec-policy matching and amendment derivation in
codex-rs/core/src/exec_policy.rs:571. - Reuse wrapper extraction robustness similar to
codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs:544(which scans argv for-c/-lctriples instead of requiring strict argv shape). - Extend shell command extraction/parsing beyond strict 3-token shell forms in
codex-rs/shell-command/src/bash.rs:97. - Handle env-prefix forms (
KEY=VALUE cmd ...) before policy lookup. - Keep approval-cache canonicalization and policy normalization aligned (
codex-rs/core/src/command_canonicalization.rs:14,codex-rs/core/src/tools/runtimes/shell.rs:127,codex-rs/core/src/tools/runtimes/unified_exec.rs:87).
Relevant current behavior in code:
commands_for_exec_policy(...)falls back to raw argv when shell script parsing fails (codex-rs/core/src/exec_policy.rs:571).- Shell extraction currently assumes exact
[shell, -c/-lc, script]form (codex-rs/shell-command/src/bash.rs:97). - Tests explicitly reject variable assignment prefixes in the shell parser (
codex-rs/shell-command/src/bash.rs:425), which likely contributes to env-prefix mismatch behavior.
Potentially related reports:
- #10920
- #12095
- #10321
- #8980
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
This issue is not a duplicate of https://github.com/openai/codex/issues/11298.
The original issue is about the
prefix_ruleforbidden rules bypassed by the models by the use ofbash -lc,zsh -lcor other prefixes. In that sense this issue is duplicate of https://github.com/openai/codex/issues/10920.I’ve done additional testing and I think the issue is slightly different than I originally thought.
Environment:
Current behavior
During normal coding workflows, Codex frequently requests escalations using full PowerShell-wrapped command invocations such as:
When I click “Always allow”, Codex persists that wrapped invocation directly into:
Example generated rule:
This behaves almost like an exact-command match rather than a reusable prefix rule.
For example:
``
powershell
``dart format lib/foo.dart
``
powershell
``dart format lib/bar.dart
I also reproduced this in a completely fresh test workspace. Asking Codex to create a Flutter project generated this rule:
Manual workaround
I manually edited
default.rulesand added broad rules myself:These rules do work in some scenarios, which suggests the underlying rule engine is capable of evaluating generalized inner-command prefix rules correctly.
Important additional observation
I originally thought the issue was specifically that the “Always allow” flow was writing rules incorrectly. However, after more testing, I no longer think that is the complete explanation.
In one controlled test, I explicitly asked Codex to generate an escalation request for
flutter analyze, and the resulting approval request was normalized correctly. Clicking “Always allow” generated a reusable rule in the expected format.So Codex Desktop is clearly capable of generating normalized inner-command escalation requests that produce reusable
prefix_ruleentries.However, during normal coding workflows, Codex still frequently emits wrapped PowerShell command forms like:
Those wrapped forms do not appear to match the broad manually-authored rules consistently, even though the equivalent normalized command would.
So at this point, the issue appears to be inconsistent command normalization/canonicalization before rule matching and persistence:
This seems closely related to PR #20336, but there are still Windows Desktop command paths that do not appear to be using the normalized inner-command representation consistently.