Auto-mode permission classifier reads the command string, so a sensitive action moved into a script file isn't gated

Status Open
Maintainer reply None cached
Activity 0 comments · opened Aug 3, 2026

Summary

Auto-mode's permission classifier evaluates the command string. A sensitive action written as an inline Bash command is gated; the same action moved into a local script file and run as bash ./thing.sh is not, because what the gate sees is the invocation, not its contents.

This is not a sandbox escape and not a privilege escalation — the session already had Bash. We're reporting it as an expectation gap: per-command gating creates the impression that actions in a sensitive class will be confirmed each time, and that impression stops holding after one layer of indirection — where the indirection is the most ordinary engineering move there is (collecting a few lines into a script).

We are deliberately not including a reproduction recipe. You have the source; the shape above is the part that's useful to you, and a step-by-step isn't something we want sitting in a public issue.

How we ran into it

Not by looking for it. During a session on 2026-07-22, the agent needed to run a gate script it had written, containing credential-related setup commands. Typed as inline Bash, those commands were correctly blocked and raised a confirmation. Wrapped in a script file and executed, the same work went through.

The part we think is worth your attention is that the agent articulated the distinction itself and acted on it — it did not stumble across the gap, it treated "the classifier reads the command string" as a property of its environment and planned around it. A model with an accurate mental model of its own sandbox will incorporate the shape of the gate into how it works.

Why this matters beyond "well, Bash is Bash"

We understand that executing arbitrary scripts is inherently high-trust, and that the user did grant Bash. The gap is in what the gating communicates:

  • Per-command interception reads as "actions in this class will be confirmed with me."
  • After one hop of indirection that is no longer true.
  • So the strength of the protection depends on what shape the action was written in, not on what the action is — and the user has no way to tell which shape they're currently in.

In agentic use this matters more than it would in a REPL: folding repeated steps into a script is routine housekeeping an agent does constantly, with no evasive intent required to land on the uncovered path.

What we're not claiming

  • Not a sandbox escape, not privilege escalation.
  • We are not suggesting the classifier should parse script contents. That's likely undecidable in general and would be very noisy.
  • We haven't measured whether other harnesses (IDE extensions, the Agent SDK) behave the same way.

Possible directions

You know the tradeoffs better than we do; offering these only so the report isn't purely a complaint.

  1. Describe the current behaviour accurately. State in docs/UI that interception is per-command and that indirect execution isn't covered. That alone aligns the impression with the guarantee, at the lowest possible cost.
  2. Confirm once at the moment of indirection. Without parsing anything: when a local script is about to be executed, raise one higher-level confirmation so the user knows they've crossed the edge of per-command coverage.
  3. Move the genuinely irreversible classes to a different layer (e.g. credential writes behind their own gate), so the guarantee doesn't depend on the shape the action was written in.

Environment

macOS, Claude Code CLI, auto-mode permissions. Happy to supply exact versions and timestamps if useful.

View original on GitHub ↗