Skip to content

bug: permission.skill pattern rules are not fully enforced in skill exposure flow #21793

Closed as not planned

Description

@membphis

Description

When permission.skill uses a pattern rule like \"lark-*\": \"deny\", matching skills are still exposed to the model.

I expected Lark skills such as lark-doc, lark-base, and lark-mail to be unavailable, but they still appear in the available skills list.

Plugins

opencode

OpenCode version

1.4.1

Steps to reproduce

  1. Add this global config:
{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "skill": {
      "lark-*": "deny"
    }
  }
}
  1. Start opencode
  2. Open a normal session where skills are included in the prompt/tool descriptions
  3. Inspect the available skills shown to the model

Expected behavior

Skills matching lark-* should not be exposed to the model.

Actual behavior

Skills matching lark-* still appear in the available skills list.

Screenshot and/or share link

No response

Operating System

ubuntu 24, arm64

Terminal

Ghostty

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    needs:complianceThis means the issue will auto-close after 2 hours.
    on Apr 10, 2026
  2. github-actions commented on Apr 10, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • The issue description appears to be AI-generated. It contains an extensive wall of text with elaborate sections (Analysis, Suspected root cause, Suggested Fix, regression test recommendations, etc.) that go well beyond what a normal bug report requires. AI-generated walls of text are not acceptable per our contributing guidelines.

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.

    If you believe this was flagged incorrectly, please let a maintainer know.

  3. membphis commented on Apr 10, 2026

    @membphis
    Author

    I got this patch by opencode itself:

    $ cat bugfix.patch
    diff --git a/packages/opencode/src/permission/index.ts b/packages/opencode/src/permission/index.ts
    index b2cc0f9bb..e538818c2 100644
    --- a/packages/opencode/src/permission/index.ts
    +++ b/packages/opencode/src/permission/index.ts
    @@ -300,9 +300,7 @@ export namespace Permission {
         const result = new Set<string>()
         for (const tool of tools) {
           const permission = EDIT_TOOLS.includes(tool) ? "edit" : tool
    -      const rule = ruleset.findLast((rule) => Wildcard.match(permission, rule.permission))
    -      if (!rule) continue
    -      if (rule.pattern === "*" && rule.action === "deny") result.add(tool)
    +      if (evalRule(permission, "*", ruleset).action === "deny") result.add(tool)
         }
         return result
       }
    diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts
    index 09788f3cd..16b3965bd 100644
    --- a/packages/opencode/src/session/system.ts
    +++ b/packages/opencode/src/session/system.ts
    @@ -64,6 +64,7 @@ export namespace SystemPrompt {
         if (Permission.disabled(["skill"], agent.permission).has("skill")) return
    
         const list = await Skill.available(agent)
    +    if (list.length === 0) return
    
         return [
           "Skills provide specialized instructions and workflows for specific tasks.",
    diff --git a/packages/opencode/src/tool/skill.ts b/packages/opencode/src/tool/skill.ts
    index 276f3931d..3b605e7e6 100644
    --- a/packages/opencode/src/tool/skill.ts
    +++ b/packages/opencode/src/tool/skill.ts
    @@ -12,37 +12,10 @@ const Parameters = z.object({
     })
    
     export const SkillTool = Tool.define("skill", async () => {
    -  const list = await Skill.available()
    -
    -  const description =
    -    list.length === 0
    -      ? "Load a specialized skill that provides domain-specific instructions and workflows. No skills are currently available."
    -      : [
    -          "Load a specialized skill that provides domain-specific instructions and workflows.",
    -          "",
    -          "When you recognize that a task matches one of the available skills listed below, use this tool to load the full skill instructions.",
    -          "",
    -          "The skill will inject detailed instructions, workflows, and access to bundled resources (scripts, references, templates) into the conversation context.",
    -          "",
    -          'Tool output includes a `<skill_content name="...">` block with the loaded content.',
    -          "",
    -          "The following skills provide specialized sets of instructions for particular tasks",
    -          "Invoke this tool to load a skill when a task matches one of the available skills listed below:",
    -          "",
    -          Skill.fmt(list, { verbose: false }),
    -        ].join("\n")
    -
       return {
    -    description,
    +    description: "",
         parameters: Parameters,
         async execute(params: z.infer<typeof Parameters>, ctx) {
    -      const skill = await Skill.get(params.name)
    -
    -      if (!skill) {
    -        const available = await Skill.all().then((x) => x.map((skill) => skill.name).join(", "))
    -        throw new Error(`Skill "${params.name}" not found. Available skills: ${available || "none"}`)
    -      }
    -
           await ctx.ask({
             permission: "skill",
             patterns: [params.name],
    @@ -50,6 +23,13 @@ export const SkillTool = Tool.define("skill", async () => {
             metadata: {},
           })
    
    +      const skill = await Skill.get(params.name)
    +
    +      if (!skill) {
    +        const available = await Skill.all().then((x) => x.map((skill) => skill.name).join(", "))
    +        throw new Error(`Skill "${params.name}" not found. Available skills: ${available || "none"}`)
    +      }
    +
           const dir = path.dirname(skill.location)
           const base = pathToFileURL(dir).href
  4. github-actions commented on Apr 10, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now follows the contributing guidelines and the needs:compliance label has been removed.

  5. changed the title [-]permission.skill pattern rules are not fully enforced in skill exposure flow[/-] [+]bug: permission.skill pattern rules are not fully enforced in skill exposure flow[/+] on Apr 10, 2026
  6. added a commit that references this issue on Apr 10, 2026
    0ed806d
  7. rekram1-node commented on Apr 10, 2026

    @rekram1-node
    Contributor

    This works as expected rn:

     "agent": {
        "build": {
          "permission": {
            "skill": {
              "another-*": "deny",
            },
          },
        },
      },
    

    Maybe run opencode debug skill show me what's falling through?

  8. malhashemi commented on Apr 14, 2026

    @malhashemi
    Contributor

    This works as expected rn:

     "agent": {
        "build": {
          "permission": {
            "skill": {
              "another-*": "deny",
            },
          },
        },
      },
    

    Maybe run opencode debug skill show me what's falling through?

    Not really, all skills even denied ones are showing in the skill tool description, the available skill xml block in the system prompt is working fine as well as the deny behaviour, whats no longer working is hiding the denied skills.

  9. hu-qi commented on Apr 22, 2026

    @hu-qi

    the same.

    Image
  10. removed
    bugSomething isn't working
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  11. kapilratnani commented on May 28, 2026

    @kapilratnani

    Facing the same bug. Filed : #29727 . I working on creating isolated opencode environment as part of this project : https://github.com/kapilratnani/aienv . What is needed to get this prioritized ?

  12. github-actions commented on Jul 28, 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