anomalyco / anomalyco/opencode
permission.edit patterns are matched against worktree-relative paths — absolute/~ patterns silently never match (fail-open for deny rules)
@jlongster is already working on this.
Since Aug 6, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Summary
permission.edit (and by extension write) rules are matched against the worktree-relative path of the file being edited, not the absolute path. Any rule using an absolute path or ~ pattern silently never matches. This is fail-open for deny rules: a rule like "~/.ssh/**": "deny" looks like it protects a directory but does nothing.
Environment
- opencode 1.18.13 (Homebrew, macOS)
- Config:
~/.config/opencode/opencode.jsonc
Root cause
The edit/write tools submit a worktree-relative path as the permission pattern:
packages/opencode/src/tool/write.ts:56—patterns: [path.relative(instance.worktree, filepath)]packages/opencode/src/tool/edit.ts:104and:147— same
For a file outside the worktree this yields paths with ../.. segments (e.g. ../../daily-notes/2026-08.md), which absolute/~ patterns can never match.
Repro
- Global config:
{
"agent": {
"writer": {
"mode": "all",
"permission": {
"bash": "deny",
"edit": { "*": "deny", "~/daily-notes/**": "allow" }
}
}
}
}
- Run:
opencode run --agent writer "Create the file ~/daily-notes/test.txt containing ok"
Expected: edit allowed by the ~/daily-notes/**" allow rule.
Actual: denied — the submitted pattern is relative (e.g. ../../daily-notes/test.txt from a repo cwd, Users/<name>/daily-notes/test.txt from /tmp), so the allow rule never matches and "*": "deny" wins.
The fail-open direction (security)
"edit": { "*": "allow", "~/.ssh/**": "deny" }
A user writing this believes ~/.ssh is protected. The deny rule never matches, so the agent can edit ~/.ssh/* freely. Any absolute-path deny rule for edit/write is currently a no-op.
Workaround (what I had to do)
Use relative patterns that anticipate ../ segments, which is undocumented and fragile:
"edit": { "*": "deny", "daily-notes/**": "allow", "*/daily-notes/**": "allow" }
This also over-broadens the rule: any directory named daily-notes anywhere becomes writable.
Suggestion
Resolve the submitted pattern to an absolute path before matching (or match against both absolute and relative forms), so absolute and ~ patterns work as users expect. At minimum, document that edit/write permission patterns are worktree-relative and that absolute/~ patterns do not work.
Happy to provide more detail or test a fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.