Skip to content

Conversation

@jgordijn
Copy link

@jgordijn jgordijn commented Dec 21, 2025

Closes #5395

Summary

Adds polymorphic configuration for external_directory permission, allowing users to:

  • Split read/write permissions separately
  • Define directory-specific rules with glob patterns
  • Use tilde (~) for home directory paths

Example Configuration

{
  "permission": {
    "external_directory": {
      "read": {
        "directories": {
          "~/projects/docs": "allow",
          "~/.ssh": "deny"
        },
        "default": "ask"
      },
      "write": "deny"
    }
  }
}

Changes

  • Schema: Added polymorphic external_directory config (string OR read/write split OR directory rules)
  • Permission resolver: New ExternalPermission.resolve() utility for path-based permission resolution
  • Tool integration: Added permission checks to read, write, edit, patch, ls, glob, grep
  • Glob patterns: * matches within directory, ** matches across directories
  • Documentation: Updated permissions docs with examples and limitations

Screenshot

opencode-screenshot

The screenshot shows:

  • Reading files from an allowed external directory works
  • Reading from a denied directory shows clear error message
  • Write operations to read-only directories are blocked

Known Limitations

  • bash tool uses best-effort detection (documented)
  • Symlink escape vulnerability tracked as follow-up
  • LSP tools bypass tracked as follow-up

Testing

  • 28 new tests for ExternalPermission.resolve()
  • All 345 tests pass

…st#5395)

- Support simple string and object-based permission configs
- Enable read/write operation split with directory rules
- Maintain backward compatibility with existing configs
…es (sst#5395)

- Create ExternalPermission.resolve() for polymorphic permission handling
- Support read/write split with directory-specific rules
- Implement tilde expansion for home directory patterns
- Update all tools to use operation-specific permission checks
- Add comprehensive test coverage (21 tests)
…ls (sst#5395)

- Add permission checks to ls, glob, and grep tools
- Check Filesystem.contains() before accessing external paths
- Use ExternalPermission.resolve() with 'read' operation
- Prompt or deny access consistently with read.ts behavior
…st#5395)

- Add Wildcard.pathMatch() where * doesn't cross directory boundaries
- Add Wildcard.pathAll() for file path pattern matching
- ** now correctly matches across directories, * matches within
- Update ExternalPermission to use pathAll() for directory rules
- Add comprehensive tests for new path matching behavior
…t#5395)

- Use path.join() instead of string concat for Windows compatibility
- Correctly handles path separators on all platforms
…sst#5395)

Patterns like /path/**/subdir now correctly match files inside subdir
by automatically appending /** unless pattern already ends with *
Changed from 'is not in the current working directory' to
'is denied by external_directory permission' for clarity
Document read/write split, directory rules, glob patterns, and limitations
**/ now uses (?:.*/)? regex to ensure path segment boundaries.
/a/**/docs no longer incorrectly matches /a/xdocs
- Correct bash behavior (best-effort detection, not unrestricted)
- Add patch to the list of covered tools
- Add symlink limitation warning
- Make Wildcard.pathAll generic to avoid 'any' type
- Replace 'let' with 'const' in glob.ts and grep.ts
@jgordijn
Copy link
Author

@thdxr Can I do anything to get this accepted?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Split external_directory permission into read vs write

1 participant