Skip to content

Bug: permission pathing crossplatform #7279

Closed as not planned
Closed as not planned

Description

@KoalaHao

Description

      "permission": {
        "edit": {
          "*": "deny",
          "myPath/*": "allow",

this fails to match on windows, because the path would be myPath\*

Plugins

No response

OpenCode version

1.1.6

Steps to reproduce

  1. windows
  2. set edit permission to deny, set a specific path with forward slash / to allow, eg myPath/*
  3. tell agent to edit a file in that path
    opencode denies edit
  4. set path to back slash, eg myPath\*
    opencode allows edit to that directory

Screenshot and/or share link

No response

Operating System

windows

Terminal

No response

Activity

  1. github-actions commented on Jan 8, 2026

    @github-actions
    Contributor

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

    This bug highlights a critical flaw in path-based permission matching when using forward slashes on Windows systems. The path normalization issue affects the core functionality requested in those feature issues.

  2. pschiel commented on Jan 28, 2026

    @pschiel
    Contributor

    #6763 fixes this via path normalization

  3. moonxorsun commented on Feb 25, 2026

    @moonxorsun

    I can confirm this issue still exists in v1.2.8 and is particularly problematic for custom agents defined in markdown files (agents/*.md).

    After diving into the opencode source code to debug why .opencode/plans/*.md was working for the built-in plan agent but failing for my custom analyze agent on Windows, here is the exact root cause:

    1. How write.ts / edit.ts check permissions:
      Tools like write.ts pass the relative path to ctx.ask:

      patterns: [path.relative(Instance.worktree, filepath)]

      On Windows, path.relative produces a path with backslashes (e.g., .opencode\plans\test.md).

    2. Why the built-in plan agent works:
      In src/agent/agent.ts, the built-in plan agent constructs its permission rule using path.join:

      edit: {
        "*": "deny",
        [path.join(".opencode", "plans", "*.md")]: "allow",
      }

      This generates the pattern .opencode\plans\*.md dynamically on Windows, which perfectly matches the tool output above.

    3. Why custom Agent configs fail:
      When defining an agent in agents/my-agent.md, we typically write:

      permission:
        edit:
          "*": deny
          ".opencode/plans/*.md": allow

      This is parsed exactly as-is. The pattern is .opencode/plans/*.md (with forward slashes).

    4. The gap in Wildcard.match (src/util/wildcard.ts):
      While Wildcard.match attempts to normalize paths:

      if (str) str = str.replaceAll("\\", "/")
      if (pattern) pattern = pattern.replaceAll("\\", "/")

      This logic executes during the match evaluation (PermissionNext.evaluate). However, there seems to be a disconnect where the findLast lookup or the initial ruleset merging either ignores this normalized pattern or the Windows path \ fails to match the / based globs before it reaches this normalization.

    Workaround:
    For custom agents on Windows, you must escape the Windows path separator in the YAML file:

    permission:
      edit:
        "*": deny
        ".opencode\plans\*.md": allow

    Proposed Fix:
    The easiest fix would be for the config parser (PermissionNext.fromConfig) to run .replaceAll("\\", "/") on all pattern keys immediately upon loading them, or to enforce a standard separator representation throughout the permission state instead of normalizing it at the very end in Wildcard.match.

  4. MichaelYochpaz commented on Mar 24, 2026

    @MichaelYochpaz
    Contributor

    I'm getting this on v1.3.0 with agent-level permissions in opencode.json.

    In my case, a custom agent uses ~/.config/opencode/.tmp/** as an allow pattern for edit.
    After tilde expansion on Windows, the pattern becomes C:\Users\<user>/.config/opencode/.tmp/** (mixed separators), which fails to match the fully backslash-resolved path the Write tool passes.

  5. KoalaHao commented on Mar 25, 2026

    @KoalaHao
    Author

    its almost 3 months now devs are overwhelmed by the amount of issues and pull requests, i dont see this getting fixed anytime soon

  6. github-actions commented on Jul 3, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions