Repository navigation
Description
Description
I asked OpenCode to write this bug report below. I didn't read it carefully, so here's my short version:
I have:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": "deny"
}
}… but OpenCode was able to read on the parent dir, and there are no rules allowing that path in any global config. I added two screenshots.
Bug: external_directory: "deny" is bypassed by the bash tool (macOS)
Summary
With permission.external_directory set to deny, the dedicated file tools
(read, edit, glob, grep) correctly block paths outside the project
worktree, but the bash tool can still read (and presumably write) those same
paths with no prompt and no error. This makes the setting ineffective as a
project-boundary guard rail.
Environment
- opencode: latest, via ACP inside WebStorm (not the standalone CLI)
- OS: macOS 27.0.1
- Shell:
/bin/zsh auto-approve: off
Config
Project is a nested git repo, so its worktree root is the project root
~/w/parent0/parent1. Config:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"external_directory": "deny"
}
}The parent directory ~/w/parent0 is outside this worktree (it is a
separate, outer git repo). ../README.md resolves to ~/w/parent0/README.md,
which is external.
Steps to reproduce
- Open the project rooted at
~/w/parent0/parent1
(its own git worktree) and start a session with the config above. - Ask the agent to read
../README.md(i.e.~/w/parent0/README.md).
Expected
All tools should be blocked from touching the external path, per the docs:
"Use external_directory to allow tool calls that touch paths outside the
working directory where OpenCode was started. This applies to any tool that
takes a path as input (for example read, edit, glob, grep, and many
bash commands)."
Actual
-
readtool is correctly blocked. Attempting to read
~/w/parent0/README.mdreturns:The user has specified a rule which prevents you from using this specific tool call. [{"permission":"*","action":"allow","pattern":"*"}, {"permission":"external_directory","pattern":"*","action":"ask"}, ... {"permission":"external_directory","action":"deny","pattern":"*"}, ...](the final
external_directory -> * -> denyrule fires as intended) -
bashtool is NOT blocked. In the same restricted session, all of the
following ran without a prompt and returned the external content:ls -la ~/w/parent0 git -C ~/w/parent0 remote -v git -C ~/w/parent0 log --oneline -3 cat ~/w/parent0/README.md # would read external file
So the boundary is bypassed simply by using a shell command instead of the
structured file tools, including via-C/absolute paths that never touch the
project directory.
Impact
Any rule a user relies on to keep the agent inside the project (secrets, sibling
repos, ~, system paths) is trivially bypassed through bash. The two paths
diverge: read/edit honor external_directory, bash does not.
Related existing issues
- external_directory: "deny" gets bypassed depending on which bash command you use (macOS) #44728 —
external_directory: "deny"gets bypassed depending on which bash
command you use (macOS, same per-command inconsistency) - Security: external_directory does not gate PowerShell/bash file writes on Windows #46398 —
external_directorydoes not gate PowerShell/bash file writes (Windows) - external_directory does not fire for many bash commands that write outside the project #40159 —
external_directorydoes not fire for many bash commands that write
outside the project (Linux) - Shell redirection bypasses the external_directory permission #42979 — Shell redirection bypasses the
external_directorypermission
This report confirms the same gap on macOS/zsh and on the ACP surface.
Suggested direction
- Apply the same path guard used by
read/editto paths parsed out ofbash
commands (arguments, redirection targets, and-C/absolute paths), or - Explicitly document that
external_directorydoes not cover shell commands,
and provide a supported way to sandboxbashto the worktree.
Plugins
No response
OpenCode version
1.19.0
Steps to reproduce
No response
Screenshot and/or share link
Operating System
macOS 27.0.0
Terminal
No response

Activity
opencode-agent commentedon Oct 11, 2026
Thanks for the report. I think this is a duplicate of #44728, which reports the same bypass on macOS:
external_directory: "deny"blocksreadwhile bash commands likels/catcan still reach paths outside the project.Possible duplicates and closely related issues, ordered from most to least likely:
external_directory: "deny"is enforced or not depending on which bash command touches the external path.>,tee, etc.) bypassesexternal_directory. Same cause: the bash tool only checks paths for some commands.external_directorydoesn't fire for many bash commands (closed as stale, same cause).The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
opencode-agent commentedon Oct 12, 2026
Closing this as a duplicate of #44728, which reports the same problem on macOS:
external_directory: "deny"blocksread, but bash commands likels,catandgit -Ccan still reach paths outside the project. We waited a day in case this was a different problem, and there was no reply. Please follow #44728 for updates (the shell redirection case is #42979). If your case turns out to be different, reply here and explain how, and we can reopen it. Thanks for the detailed report!