Feature Request: Skill-scoped permissions
Problem
Claude Code's permission system only allows global or project-level allow/deny rules for tools and Bash commands. There is no way to scope permissions to a specific skill.
When a user trusts a skill (e.g., /update-servers) to perform its job — SSH into known hosts, write temp scripts, read log files — they must manually enumerate every command pattern in settings.json. This is:
- Fragile: Any variation in command format (compound commands, different flags) breaks the match
- Tedious: The user must know in advance every Bash pattern the skill will use
- Counterintuitive: Users think in terms of skills, not individual tool calls
Desired Behavior
Allow permissions to be scoped to a named skill:
{
"permissions": {
"skills": {
"update-servers": {
"allow": ["Bash(*)", "Read(/tmp/*)"]
}
}
}
}
Or alternatively, allow skills to declare their required permissions in SKILL.md frontmatter:
---
name: update-servers
description: Updates remote servers via SSH
permissions:
allow:
- "Bash(ssh *)"
- "Bash(bash /tmp/update-servers-*.sh)"
- "Read(/tmp/update-*.log)"
---
The user would be asked once (at skill invocation or installation) to approve the declared permissions, similar to how mobile apps request permissions.
Why This Matters
Skills are the primary mechanism for extending Claude Code with custom workflows. Without skill-scoped permissions, every skill that runs shell commands degrades the user experience — either:
- The user is constantly prompted (friction), or
- The user grants overly broad global permissions (security risk)
Skill-level trust is a natural mental model: "I trust this skill to do its job."
Current Workaround
Manually adding pattern rules to settings.json for every command the skill might run — a brittle, incomplete solution that breaks when the skill uses compound commands or argument variations that don't match the glob.
Environment
- Claude Code CLI
- Skills system (user-defined SKILL.md files)
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
This mental model feels right: people trust a skill as a unit, not a pile of glob patterns.
One thing I would add to the proposal is making the permission decision inspectable in two places:
That split would prevent two common failure modes:
So I’d pair skill-scoped permissions with an
active_skill/permission_sourcefield in hook and transcript events. Then security/debugging does not depend on guessing from the text around the tool call.We've been dealing with this exact friction and built a meta-skill (
/make-skill-autonomous) specifically to work around the gap: it inspects recent transcripts, finds tool calls that triggered permission prompts, and adds the corresponding glob patterns tosettings.jsonautomatically.It works, but it's the wrong abstraction. The result is a flat global allowlist that grows over time with patterns from many different skills — no way to audit which skill "owns" a given entry, and no way to revoke permissions for one skill without potentially breaking another.
The SKILL.md frontmatter approach in the original proposal feels like the right model to us. Skills already declare their identity, purpose, and invocation instructions in that file —
permissions_requiredwould fit naturally there. When a user explicitly invokes/skill-name, they've already expressed trust in that skill; requiring them to also manually expand a global pattern list is redundant and undermines the "skills as units of trust" mental model.One addition worth considering: a way to see which permissions are currently active because of a skill invocation, so users can audit and revoke at the skill level rather than hunting through glob patterns.
Adding a concrete use case and a vote for the invocation-scoped ("just this run") variant of this.
I have a startup skill that, on invocation, runs ~15–20 tool calls in sequence: several
Bashcalls (find/grep/date), a dozen MCP calls across multiple connectors, and a few file edits. I want to approve the whole skill run once and have that approval auto-expire when the skill finishes — not persist tosettings.json, and not flip the entire session intobypassPermissions.Today the only options are:
--dangerously-skip-permissions/bypassPermissions— session-wide and too broad; I have to remember to toggle it back off afterward.acceptEdits— doesn't cover Bash or MCP tool calls, so it barely helps for a skill like this.permissions.allowpatterns — durable (overkill for an occasional run) and brittle for compound Bash commands.The ephemeral, auto-expiring manifest in #59314 (approve once for a bounded unit of work, expires on completion) is exactly the right mechanism — I'd just want it triggered at skill invocation rather than at plan approval: show the manifest of tools/globs the run will touch, approve once, auto-expire when the run completes or I send a new message.
Skill-declared permissions in
SKILL.mdfrontmatter (as proposed here) would be a great durable complement, but the per-invocation approve-once is the piece that removes the friction without leaving standing grants.