Skip to content

edit permission uses relative paths but external_directory uses absolute paths, breaking agent-level path rules #20045

@fluency03

Description

@fluency03

Description

When configuring agent-level permissions with absolute path patterns, external_directory works correctly but edit silently fails to match because they use different path formats internally.

Agent config (YAML frontmatter):

permission:
  edit:
    "*": ask
    "/tmp/my-tmp-folder/**": allow
  external_directory:
    "/tmp/my-tmp-folder/**": allow

Expected: Both permissions resolve to allow for files under /tmp/my-tmp-folder/.

Actual: external_directory resolves to allow, but edit resolves to ask (prompts the user).

Root cause

In write.ts (line 26) and edit.ts (line 45), the edit permission check passes a relative path:

await ctx.ask({
  permission: "edit",
  patterns: [path.relative(Instance.worktree, filepath)],
  // ...
})

But in external-directory.ts (line 18), the external_directory check passes an absolute path:

const glob = path.join(dir, "*")
await ctx.ask({
  permission: "external_directory",
  patterns: [glob],
  // ...
})

For non-git projects, Instance.worktree is / (as noted in the comment in instance.ts). So:

path.relative("/", "/tmp/my-tmp-folder/file.md")
// -> "tmp/my-tmp-folder/file.md"   (no leading slash)

The configured pattern /tmp/my-tmp-folder/** produces regex ^/tmp/my-tmp-folder/.*$, which does NOT match tmp/my-tmp-folder/... (missing leading /).

The "*": ask catch-all is the last matching rule, so the user gets prompted.

Steps to reproduce

  1. Create an agent markdown file with the config shown above
  2. Start OpenCode in a non-git directory (so Instance.worktree is /)
  3. Have the agent write a file to /tmp/my-tmp-folder/test.md
  4. Observe the permission prompt despite the allow rule

Suggested fix

Normalize the path format so edit and external_directory use the same representation when matching against permission rules. Either:

  • Use absolute paths consistently in both checks, or
  • Document clearly that edit patterns are relative to the worktree and external_directory patterns are absolute

The first option is better UX since users configure both in the same permission block and expect the same path format.

Environment

  • OpenCode version: 1.3.0
  • OS: macOS (arm64)

Issue is discovered by OpenCode :)

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions