[Bug] Sandbox re-expands permissions.deny globs on every Bash call causing 1.6s/glob overhead

Status Open
Reported on v2.1.223
Maintainer reply None cached
Activity 1 comment · opened Aug 7, 2026

Bug Description

Title:
Sandbox re-expands permissions.deny globs on every Bash call: 1.6s per glob (24s overhead on a trivial command)

Body:
Claude Code 2.1.223 | WSL2 (Linux 6.18.33.2-microsoft-standard-WSL2) | bubblewrap 0.9.0
Workspace: 278,775 files

SUMMARY
Each "**/"-rooted Read(...) glob in permissions.deny adds ~1.6s of sandbox
setup to EVERY Bash tool call. With 15 such globs, echo hi took 24.1s of
overhead on 0.03s of actual work. Removing the globs: 0.55s. A 44x penalty
from a config most users would consider modest.

REPRO

  1. Set 15 Read(/...) globs in permissions.deny (e.g. /.env, **/id_rsa*,

**/.key, */credentials.json).

  1. Run a trivial Bash command that prints time.time() before and after its

own body.

  1. Compare the in-shell start timestamp against the tool call's start.

The gap is pre-execution overhead.

MEASURED (one variable at a time, config restored between each)
deny-list shape overhead
0 globs 0.53s
1 anchored literal path 0.53s <- free, no walk
1 tree-rooted Read(**/.env) 1.9s
15 tree-rooted (realistic config) 24.1s
40 tree-rooted 60.2s
Linear at ~1.6s per tree-rooted glob. A-B-A confirmed: 24.0 -> 60.2 -> 24.2.

MECHANISM
The globs are not passed to the sandbox as patterns. On every Bash call they
are expanded against the filesystem and each match is bind-mounted. Evidence:

  • The live sandbox policy lists resolved paths (".../project-api/.env.local"),

not "**/.env.local".

  • Deleting a matched file from inside the sandbox fails with "Device or

resource busy" - the bind mount is live.
So each "**/" glob is a full recursive tree walk, per glob, per command. Cost
scales with glob count x tree size.

WHY IT'S BAD
The expansion appears to be recomputed per command rather than cached. The
deny list changes rarely; the tree changes rarely. The result is that a
security config the docs encourage silently makes the tool unusable on a
large workspace, with no diagnostic surfacing the cause. It took a day of
bisecting to find.

Anchored rules (Read(project-api/.env.local)) are free, but that is not
documented, and it trades away the coverage that makes "**/" worth using.

SUGGESTED FIX
Cache the expansion per session, invalidating on settings change; or pass the
patterns to the sandbox and match at access time instead of pre-expanding; or
at minimum warn when deny-glob expansion exceeds some threshold.

Environment Info

  • Platform: linux
  • Terminal: wsl-Ubuntu
  • Version: 2.1.223
  • Feedback ID: ce3c9313-b3d0-4ab8-9dcf-fe7fcd522592

Errors

[]

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗