CASE · Minor · tool-misuse
VerifiedFirsthand record--allowedTools was supposed to fence the agent in, but the global allow rules were still there
A fixer sub-agent was meant to be limited with --allowedTools, yet whoami, which was not on the list, ran. An unscoped Write permission could write files outside the agent's git worktree.
2 min read
- OBSERVED
- CATEGORY
- tool-misuse
- BLAST RADIUS
- data
- DETECTED BY
- manual-observation
- TAGS
- #claude-code #permissions #allowed-tools #sandbox #isolation #worktree
CH 1
Cause
--allowedTools did not cancel the broad allow rules in the user's global settings. Instead of meaning "only these", it worked as "also let these through without asking", on top of everything already allowed.
CH 2
Consequence
It was caught while measuring the isolation in a throwaway repository, before any real use, so there was no damage. Shipped as designed, the fixer agent could have modified files outside its target.
CH 3
Fix
Global settings were dropped with --setting-sources "", Edit and Write were scoped to the worktree path, and the sandbox was enabled. Commits now happen outside the isolation, done by the server, and push is blocked twice over. Isolation is not trusted until it has been shown to hold.
What happened
A home-made multi-agent canvas was getting a new role: a “fixer” that repairs the
problems an investigation turns up. The fixer is a child agent started with
claude -p, designed to work only inside a separate git worktree, never in the
target repository itself.
Its tools were narrowed with --allowedTools: reading, and editing inside the
worktree. Nothing else.
The chaos on the ground
Before using it for real, the isolation was tested against a throwaway repository.
whoami, which was not on the allow list, ran. A Write permission granted without
a path scope could create files outside the worktree. A door that was closed on
paper was open in practice.
Root cause
--allowedTools did not cancel the broad allow rules in the user’s global
settings (~/.claude/settings.json). Permissions granted for everyday interactive
work were inherited by the child agent as-is.
The option was not a fence that said “only these”. It added “also run these without asking” on top of the global rules. The name suggests one direction; it works in the other.
The fix
--setting-sources ""stops the global settings from being loaded.- Edit and Write are scoped to the work area with rules like
Edit(//<worktree path>/**). - The sandbox is enabled. Under it, Bash commands off the allow list still ran, but measurement showed they could not reach the network or write outside the work area.
- Commits are made by the server, outside the isolation, after the fixer exits. Push is blocked twice: a deny rule, plus a push-destination override limited to that process.
The lesson is simple. Isolation is not the configuration you wrote; it only counts once you have checked that it actually holds.
Sources
- Firsthand account from the site operator. There is no public write-up to link to.
Pass this record on to your team