New permission system issues with wildcards and glob patterns #4277

Closed
opened 2026-02-16 17:43:15 -05:00 by yindo · 5 comments
Owner

Originally created by @shanepadgett on GitHub (Jan 5, 2026).

Originally assigned to: @thdxr on GitHub.

Description

Below is the frontmatter in one of my agents. You can see the intent here is to deny the ability to write to any file or edit any file outside of the specific folders and filetypes I've globbed. I already checked and found one issue in the code is likely that you are using minimatch for the pattern matching, but that main issue is if you set "*": deny the whole tool no longer works. Specific patterns should take precedence over wildcard denys.

---
name: sdd/plan
description: SDD planning and artifact authoring - specs, proposals, tasks, and plans
color: "#BFB8AD"
permission:
  edit:
    "changes/**/*.md": allow
    "*": deny
  write:
    "changes/**/*.md": allow
    "*": deny
---

Plugins

No response

OpenCode version

1.1.3

Steps to reproduce

Use the agent and see that it cannot write file to such a folder.

Screenshot and/or share link

No response

Operating System

macOS 26.1

Terminal

Ghostty

Originally created by @shanepadgett on GitHub (Jan 5, 2026). Originally assigned to: @thdxr on GitHub. ### Description Below is the frontmatter in one of my agents. You can see the intent here is to deny the ability to write to any file or edit any file outside of the specific folders and filetypes I've globbed. I already checked and found one issue in the code is likely that you are using minimatch for the pattern matching, but that main issue is if you set "*": deny the whole tool no longer works. Specific patterns should take precedence over wildcard denys. ```markdown --- name: sdd/plan description: SDD planning and artifact authoring - specs, proposals, tasks, and plans color: "#BFB8AD" permission: edit: "changes/**/*.md": allow "*": deny write: "changes/**/*.md": allow "*": deny --- ``` ### Plugins _No response_ ### OpenCode version 1.1.3 ### Steps to reproduce Use the agent and see that it cannot write file to such a folder. ### Screenshot and/or share link _No response_ ### Operating System macOS 26.1 ### Terminal Ghostty
yindo added the bug label 2026-02-16 17:43:15 -05:00
yindo closed this issue 2026-02-16 17:43:15 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 5, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #6676: [BUG] Bash permission patterns with wildcards don't match commands with flags (e.g., "kill *" doesn't match "kill -9 PID") - Similar issue with wildcard pattern matching in permissions
  • #6892: MCP tool permissions not working after migration from tools to permissions - Related to the new permission system not working correctly
  • #6856: Should we actually implement the new granular permissions in .md agent files? - Discusses implementation of granular permissions in agent frontmatter

The core issue appears to be with how wildcard and glob patterns are processed in the new permission system, where specific patterns should take precedence over wildcard denies.

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Jan 5, 2026): This issue might be a duplicate of existing issues. Please check: - #6676: [BUG] Bash permission patterns with wildcards don't match commands with flags (e.g., "kill *" doesn't match "kill -9 PID") - Similar issue with wildcard pattern matching in permissions - #6892: MCP tool permissions not working after migration from tools to permissions - Related to the new permission system not working correctly - #6856: Should we actually implement the new granular permissions in .md agent files? - Discusses implementation of granular permissions in agent frontmatter The core issue appears to be with how wildcard and glob patterns are processed in the new permission system, where specific patterns should take precedence over wildcard denies. Feel free to ignore if none of these address your specific case.
Author
Owner

@malhashemi commented on GitHub (Jan 5, 2026):

@shanepadgett I think it is about ordering see 6856

@malhashemi commented on GitHub (Jan 5, 2026): @shanepadgett I think it is about ordering see [6856](https://github.com/anomalyco/opencode/issues/6856#issuecomment-3713039600)
Author
Owner

@rekram1-node commented on GitHub (Jan 5, 2026):

@shanepadgett try:

permission:
  edit:
    "*": deny
    "changes/**/*.md": allow
  write:
    "*": deny
    "changes/**/*.md": allow
@rekram1-node commented on GitHub (Jan 5, 2026): @shanepadgett try: ``` permission: edit: "*": deny "changes/**/*.md": allow write: "*": deny "changes/**/*.md": allow ```
Author
Owner

@shanepadgett commented on GitHub (Jan 6, 2026):

So switching the ordering at least allowed the write tool to be recognized, but glob patterns like my changes folder do not work still. So switching was an improvement, but when it tried to write a markdown file to changes folder it was denied.

@shanepadgett commented on GitHub (Jan 6, 2026): So switching the ordering at least allowed the write tool to be recognized, but glob patterns like my changes folder do not work still. So switching was an improvement, but when it tried to write a markdown file to changes folder it was denied.
Author
Owner

@kylerm42 commented on GitHub (Jan 7, 2026):

Just wanted to share my experience with this. The documentation does not make it clear that these read/edit/write permissions are relative to the workspace root, which is NOT always the directory you launch Opencode from. Opencode uses git rev-parse --git-common-dir to set the root, so patterns have to match from that directory.

I had my agent set up like this:

  edit:
    "*": deny
    "test_dir*": allow
  write:
    "*": deny
    "test_dir/*": allow

This is my setup that's problematic with those permissions:

repo-root/                          [Git Root, Opencode worktree root]
├── test_dir/                       ✅ Pattern: test_dir/*
│   └── file.md                        Can edit depending on external_directory permission
│
└── sub_dir/                        [Working Directory - where Opencode launches]
    └── test_dir/                   ❌ Pattern: test_dir/*
        └── file.md                    Does NOT match (full path is sub_dir/test_dir/*)

So after figuring out what the issue is, I changed my permissions to this:

  edit:
    "*": deny
    "*/test_dir*": allow
  write:
    "*": deny
    "*/test_dir/*": allow

Which leads to some other potential problems.

repo-root/                          [Git Root]
├── test_dir/                       ❌ Pattern: */test_dir/*
│   └── file.md                        Does NOT match (no prefix before test_dir)
│
└── sub_dir/                        [Working Directory - where Opencode launches]
    └── test_dir/                   ✅ Pattern: */test_dir/*
        └── file.md                    DOES match (sub_dir/ matches the */)
External Repository (SECURITY ISSUE)
=====================================
/some/other/repo/                   [Different Git Root]
└── any_dir/                        
    └── test_dir/                   ⚠️  Pattern: */test_dir/*
        └── file.md                    ALSO MATCHES! (any_dir/ matches the */)

I think it's easy enough to manage the permissions now that I know, but it took a while to figure out and diving into the code to understand. My suggestions would be to 1. standardize external_directory permission (uses Instance.directory) and read/edit/write permissions (uses Instance.worktree), and 2. Update the permissions documentation to include a note about this. @rekram1-node

@shanepadgett Not sure if this applies to your situation, but also wanted to point out that the wildcard matching is a simple one, not like glob patterns. So yours should let you edit changes/some_dir/test.md but wouldn't let you edit changes/test.md.

@kylerm42 commented on GitHub (Jan 7, 2026): Just wanted to share my experience with this. The documentation does not make it clear that these read/edit/write permissions are relative to the workspace root, which is **NOT** always the directory you launch Opencode from. Opencode uses `git rev-parse --git-common-dir` to set the root, so patterns have to match from that directory. I had my agent set up like this: ```yml edit: "*": deny "test_dir*": allow write: "*": deny "test_dir/*": allow ``` This is my setup that's problematic with those permissions: ``` repo-root/ [Git Root, Opencode worktree root] ├── test_dir/ ✅ Pattern: test_dir/* │ └── file.md Can edit depending on external_directory permission │ └── sub_dir/ [Working Directory - where Opencode launches] └── test_dir/ ❌ Pattern: test_dir/* └── file.md Does NOT match (full path is sub_dir/test_dir/*) ``` So after figuring out what the issue is, I changed my permissions to this: ``` edit: "*": deny "*/test_dir*": allow write: "*": deny "*/test_dir/*": allow ``` Which leads to some other potential problems. ``` repo-root/ [Git Root] ├── test_dir/ ❌ Pattern: */test_dir/* │ └── file.md Does NOT match (no prefix before test_dir) │ └── sub_dir/ [Working Directory - where Opencode launches] └── test_dir/ ✅ Pattern: */test_dir/* └── file.md DOES match (sub_dir/ matches the */) External Repository (SECURITY ISSUE) ===================================== /some/other/repo/ [Different Git Root] └── any_dir/ └── test_dir/ ⚠️ Pattern: */test_dir/* └── file.md ALSO MATCHES! (any_dir/ matches the */) ``` I think it's easy enough to manage the permissions now that I know, but it took a while to figure out and diving into the code to understand. My suggestions would be to 1. standardize `external_directory` permission (uses `Instance.directory`) and read/edit/write permissions (uses `Instance.worktree`), and 2. Update the `permissions` documentation to include a note about this. @rekram1-node @shanepadgett Not sure if this applies to your situation, but also wanted to point out that the wildcard matching is a simple one, not like glob patterns. So yours should let you edit `changes/some_dir/test.md` but wouldn't let you edit `changes/test.md`.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#4277