Skip to content

fix(opencode): enforce read deny rules in glob and grep results#29755

Open
Qingzhou-Joshua wants to merge 6 commits into
anomalyco:devfrom
Qingzhou-Joshua:fix/permission-deny-env-files
Open

fix(opencode): enforce read deny rules in glob and grep results#29755
Qingzhou-Joshua wants to merge 6 commits into
anomalyco:devfrom
Qingzhou-Joshua:fix/permission-deny-env-files

Conversation

@Qingzhou-Joshua
Copy link
Copy Markdown

Issue for this PR

Closes #29674

Type of change

  • Bug fix

What does this PR do?

The **/.env* deny rule in opencode.jsonc wasn't working because of three
separate bugs:

1. **/ wildcard bug (root cause)

In wildcard.ts, the **/ pattern was being processed in the wrong order.
The code first escaped regex special chars, which turned **/ into .**/,
then replaced all * with .*, meaning the placeholder for **/ got
double-expanded. The result was a regex like (.*/)+\.env.* (one-or-more
segments) instead of (.*/)? \.env.* (zero-or-more). So **/.env* never
matched .env sitting directly at the project root.

The fix stashes **/ as a placeholder character (\x01) before any other
processing, then expands it to (.*/)? last, after all * and ?
substitutions are done.

2. glob tool not filtering results

Even if the wildcard was correct, the glob tool was returning all ripgrep
matches without checking read deny rules on the result paths. Fixed by
filtering the file list against ctx.evaluate({ permission: "read", pattern: relPath }) before output.

3. grep tool not filtering results

Same issue — grep result rows weren't checked against read deny rules. Fixed
the same way.

To wire up the filtering, I added an evaluate() method to Tool.Context
that does a silent, synchronous permission check against static config rules
only (unlike ask() which also includes runtime-approved rules and triggers
the UI).

How did you verify your code works?

  • Added 4 unit tests in packages/core/test/util/wildcard.test.ts
    specifically for **/ root-level matching
  • Added 8 integration tests in
    packages/opencode/test/permission/file-pattern.test.ts covering the full
    scenario from the issue: Permission.fromConfig({ read: { "**/.env*": "deny" } }) now correctly denies .env, .env.local at root and in subdirectories,
    and the glob/grep filtering logic works correctly
  • All 17 new/updated tests pass

Screenshots / recordings

N/A — not a UI change

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Qingzhou-Joshua and others added 6 commits May 28, 2026 15:25
`**/` now correctly matches root-level files (e.g. `**/.env*` matches
`.env`). The placeholder is expanded after `*` and `?` substitution to
avoid those passes corrupting the already-expanded regex fragment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new `evaluate()` method to Tool.Context that silently checks a
permission rule against the merged agent+session ruleset without
triggering the ask UI. This enables glob and grep tools to filter out
denied file paths from their results in a future change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…co#29674)

After ripgrep collects glob results, filter out any file whose path
relative to the worktree matches a "read" deny rule via ctx.evaluate().
This prevents denied files (e.g. .env) from leaking into glob output
even when the global glob permission is allowed. Also adds a test file
and updates the glob test mock context with the evaluate() method.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…co#29674)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…y rule enforcement

Appends a new describe block with three integration tests that verify:
1. User config deny rule blocks .env at root for read
2. User config deny rule blocks .env in subfolders for read
3. Default agent rules handle .env files via pattern matching

These tests exercise the complete fix for issue anomalyco#29674, which includes:
- Wildcard fix for **/ to match root-level files
- glob tool filtering against read deny rules
- grep tool filtering against read deny rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Hey! Your PR title Fix/permission deny env files doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions
Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

I found one related PR that may be relevant to this work:

Related PR:

The other search result (#28475) is about bash environment variable patterns, which is less directly related.

Recommendation: Check if #28689 has already been merged and whether its fixes conflict with or complement the wildcard fixes in the current PR.

@Qingzhou-Joshua Qingzhou-Joshua changed the title Fix/permission deny env files fix(opencode): enforce read deny rules in glob and grep results May 28, 2026
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.

The Read, Glob, and Grep tools do not verify these rules before execution.

1 participant