Skip to content

[FEATURE]: Opt-in to bound external_directory at the instance directory, not the git worktree #54869

Open

Description

@BwunLevain

Summary

Since #7811 (fixing #7758), containsPath treats a path as inside when it is under the instance directory or the git worktree. For a CLI user working in a monorepo package that is the right default, and this is not a request to change it.

For an embedder it is a gap. We run opencode as a sidecar in a desktop app where a member chooses which folders the agent may work in, and we express that as permission.external_directory rules. When a chosen folder is a subfolder of a git repository, every path in the rest of the repository is "inside", external_directory is never consulted, and no permission rule can narrow it.

Reproduction (v1.17.11; containsPath is unchanged in v1.19.0 and on dev)

  1. Take a git repository repo/ and start an instance with its directory set to repo/tmp/x.
  2. Ask the agent to read repo/package.json: it is read at once, with no external_directory ask, even with "external_directory": { "*": "ask" }.
  3. Ask it to read a file above repo/: it asks, as expected.

Where

  • packages/opencode/src/project/instance-context.ts containsPath: contains(ctx.directory, p) || (ctx.worktree !== "/" && contains(ctx.worktree, p))
  • used by tool/external-directory.ts and tool/shell.ts
  • on dev: packages/core/src/file-access.ts

Proposal

An opt-in that makes the instance directory the only "inside" for the external_directory check, for example an env flag (OPENCODE_BOUND_TO_DIRECTORY=1) or a config key. Default behaviour unchanged.

Workaround we plan to carry until then

A plugin tool.execute.before hook that refuses file tools on paths inside the worktree but outside the folders we allow. It can refuse but not ask, and it cannot see what a shell command touches, so the engine is the right place for this.

Related

#7758 / #7811 (why the worktree counts), #46372 (per-session external_directory scoping, closed not planned), #52715 (an "always allow" that offers a whole repository above the project).

Activity

  1. opencode-agent commented on Oct 12, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed write-up, @BwunLevain!

    To restate the request: add an opt-in (env flag or config key) so that only the instance directory counts as "inside" for the external_directory check. Paths elsewhere in the same git worktree would then go through external_directory rules like any other outside path. The default would stay as it is.

    The v2 code on dev works the same way as the version you tested. FileAccess.resolve in packages/core/src/file-access.ts treats anything under location.project.directory (the worktree) as internal and never asks about external_directory. You're also right that a plugin can't fully cover this today. tool.execute.before can refuse a tool call but can't ask for permission, and it can't see which paths a shell command touches. So I haven't suggested a plugin.

    Maintainers will consider this. Related issues:

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

Metadata

Metadata

Assignees

No one assigned

    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