cd /news/developer-tools/claude-code-skill-allowed-tools-a-on… · home topics developer-tools article
[ARTICLE · art-89392] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Claude Code skill allowed-tools: a one-turn grant, not a sandbox

Anthropic's Claude Code skill system grants `allowed-tools` permissions only for the turn that invokes the skill, not for the entire session, which can confuse users expecting a persistent whitelist. The field pre-approves tools solely for that invocation, while instructions persist; `disallowed-tools` restricts tools while the skill is active. Developers should use permission settings for session-wide rules and can leverage `${CLAUDE_SKILL_DIR}` in both markdown and Bash rules to ensure scripts run without prompts.

read5 min views1 publishedAug 9, 2026

You add allowed-tools: Bash(git add *) Bash(git commit *)

to a skill. You type /commit

, and Claude stages and commits without asking. You send one more message, ask for another commit — and the permission prompt is back.

Nothing broke. allowed-tools

did exactly what it is specified to do. It is just narrower than the name suggests.

allowed-tools

pre-approves the listed tools for the turn that invokes the skill. That is the entire scope. The docs are explicit about the expiry: the grant "clears when you send your next message."

Invoking the skill again re-applies it for that turn. So /commit

, then a follow-up message asking Claude to commit again, are two different worlds: the first is covered, the second is not.

Two things happen when a skill is invoked, and they have different lifetimes:

What Lifetime
The rendered SKILL.md content
Enters the conversation as a single message and stays for the rest of the session
The allowed-tools grant
Clears when you send your next message

Instructions persist. Permissions do not.

That mismatch is why two contradictory-sounding statements are both true: the skill is still loaded and the skill stopped working. Claude still has the instructions. It just lost the pre-approval, so it asks.

If you hit this, you have two honest options:

This is the part that trips people who read the field as a whitelist:

It does not restrict which tools are available: every tool remains callable, and your permission settings still govern tools that are not listed.

So a skill with allowed-tools: Read Grep

has not been sandboxed to reading and grepping. Claude can still call Bash. The field only says "these specific ones don't need a prompt right now." Everything else falls back to your normal permission rules.

If you actually want a tool taken away, that is a different field.

disallowed-tools

is the restricting half disallowed-tools

removes tools from Claude's available pool while the skill is active. It is the right field for an autonomous skill that should never call something — a background loop that must not stop to ask you a question, for example.

Two limits worth knowing:

EndConversation

while any other tool remains.To block a tool across all skills and prompts rather than one skill, use deny rules in your permission settings.

What you want Where it goes How long it lasts
Skip prompts for a few commands when this skill runs
allowed-tools in SKILL.md
the invoking turn
Keep a tool away from one autonomous skill
disallowed-tools in SKILL.md
while the skill is active
Skip prompts for the whole session allow rules in permission settings your settings files
Block a tool everywhere deny rules in permission settings your settings files

The rule of thumb: frontmatter is for this invocation, settings are for this project or user. If you find yourself wanting allowed-tools

to stick around, you have discovered that the rule belongs in settings.

Skills can ship their own scripts. The problem is that a hardcoded path breaks the moment the skill is installed somewhere else — and for a plugin skill, ${CLAUDE_SKILL_DIR}

points at the skill's subdirectory inside the plugin, not the plugin root, so guessing is worse than it looks.

The fix is that Claude Code substitutes ${CLAUDE_SKILL_DIR}

in two places: the skill's markdown content, and Bash rules in allowed-tools

. Use the same variable in both and the allow rule matches the exact command the body tells Claude to run:

---
name: render-chart
description: Render a chart from a CSV file
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---

Run `${CLAUDE_SKILL_DIR}/scripts/render.sh <csv>` to render the chart.

Installed at ~/.claude/skills/render-chart/

, both occurrences expand to that directory, the rule matches, and the script runs without a prompt. Move the skill and it still matches, because neither side was hardcoded.

There is a sibling variable, ${CLAUDE_PROJECT_DIR}

, for project-local scripts — that one needs Claude Code v2.1.196 or later.

For skills checked into a project's .claude/skills/

directory, allowed-tools

takes effect after you accept the workspace trust dialog for that folder — the same as permission rules in .claude/settings.json

.

Read that in reverse: a skill in a repo can grant itself broad tool access, and clicking "trust" is what turns it on. Reviewing the skills is part of reviewing the repository, not a separate chore.

A 10-second pass before trusting an unfamiliar project:

grep -rn "allowed-tools\|disallowed-tools" .claude/skills/ .claude/commands/ 2>/dev/null

If a skill you did not write pre-approves Bash(* )

or anything close to it, that is worth a second look before you accept the dialog.

Bash(git commit *)

covers git commit -m "x"

, not a command routed through something else.disallowed-tools

.allowed-tools

is a receipt you hand over at the door, not a badge you wear all day. It gets you past the prompt for the turn you invoked the skill, and then it is spent. Everything durable — what Claude may do session-wide, what it may never do — lives in your permission settings.

Once you stop expecting the frontmatter to be a sandbox, the field becomes genuinely useful: it removes the friction from the two or three commands a skill actually needs, without quietly widening what Claude can do for the rest of the day.

Written while building Rulestack — packs of Cursor rules, Claude Code skills, and AGENTS.md setups for people who would rather not rediscover this by trial and error.

More notes like this as I find them: @ai-shop.bsky.social on Bluesky.

── more in #developer-tools 4 stories · sorted by recency
── more on @claude code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/claude-code-skill-al…] indexed:0 read:5min 2026-08-09 ·