If you came here to lock down a Claude skill with allowed-tools, read this first. The field does not restrict anything. That is the single most common misread of the claude skill allowed tools setting, and getting it wrong means you ship a skill you believe is fenced in when it is actually wide open.
Here is what the field does, straight from the Claude Code docs: allowed-tools grants permission for the listed tools while the skill is active, so Claude can use them without prompting you for approval. It is a pre-approval. The same docs are blunt about the limit: "It does not restrict which tools are available: every tool remains callable, and your permission settings still govern tools that are not listed." (code.claude.com/docs/en/skills)
So if your goal is least privilege, the allowed-tools frontmatter is the wrong lever on its own. The right one is below.
What allowed-tools is for
You set it to stop the approval prompts piling up during a workflow you already trust. Think of a /commit skill that runs git add, git commit, and git status. It should not have to ask permission three separate times on every single run. Pre-approve those exact calls and the skill just moves.
The field name is allowed-tools, hyphenated, in the YAML frontmatter at the top of SKILL.md. Per the Claude Code frontmatter reference, the value "Accepts a space- or comma-separated string, or a YAML list." Tool names are the tool identifiers Claude uses (Read, Grep, Bash), and Bash can carry a command pattern so you scope it tighter than the whole shell.
---
name: commit
description: Stage and commit the current changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---
That Bash(git add *) form is doing real work. It pre-approves git staging while leaving rm -rf and curl untouched. Your skill md allowed tools entry is exactly as narrow as the rule you bother to write.
Default when you omit the field: nothing is pre-approved. Claude falls back to your normal permission settings, which means it asks before running tools that are not already allowed. Omitting allowed-tools is safe. It just means more prompts.
Restricting tools when a Claude skill allowed tools list is not enough
To remove a tool from Claude's reach while a skill runs, the Claude Code frontmatter has a separate field: disallowed-tools. The docs describe it as tools "removed from Claude's available pool while this skill is active," and note the restriction clears when you send your next message. That is the lever for an autonomous skill that should never touch a particular tool.
To restrict claude skill tools more permanently, push it into your permission settings as deny rules. Deny rules in .claude/settings.json outrank a skill's pre-approvals, so a skill cannot grant itself something you have globally denied.
A concrete case. You want a code-audit skill that reads and searches but never writes, never shells out:
---
name: audit-readonly
description: Read and analyze code without modifying anything
allowed-tools: Read Grep Glob
disallowed-tools: Write Edit Bash
---
The allowed-tools line skips approval prompts on the three read tools. The disallowed-tools line keeps Write, Edit, and Bash out of the pool while the skill is live. Drop that second line and the skill can still happily write files, because pre-approving Read never un-approves Write.
Where the security framing breaks
All of this narrows what a skill does inside a session. None of it builds a sandbox.
A few hard edges before you lean on any of it. For project skills checked into .claude/skills/, the docs note that allowed-tools only takes effect after you accept the workspace trust dialog for that folder, the same as permission rules in settings, and they tell you to review project skills before trusting a repo "since a skill can grant itself broad tool access." A pulled-in skill carrying allowed-tools: Bash(*) will run arbitrary shell the moment you trust it.
The frontmatter field is also Claude Code CLI only. The Agent SDK does not read allowed-tools from SKILL.md; the docs say so directly and tell you to control access through the allowedTools option on the SDK query() instead (code.claude.com/docs/en/agent-sdk/skills). Even the SDK's skills filter "is a context filter, not a sandbox. Unlisted Skills are hidden from the model and rejected by the Skill tool, but their files remain on disk and are reachable through Read and Bash." So tool scoping does buy you a smaller blast radius. What it will never do is contain a compromised skill that already holds Bash.
For the broader review you should run before trusting any third-party skill, see the SKILL.md security audit walkthrough. If your skill ships scripts, restricting how those execute is a related and separate problem, covered in bundled scripts in a Claude skill. And for the base frontmatter every skill needs, the SKILL.md template has the name and description fields these examples assume.
The short version for skill authors
Use allowed-tools to kill approval prompts for a trusted workflow, written as narrowly as you can stand. Use disallowed-tools or settings deny rules to actually fence a skill in. Never assume the allow-list is doing the fencing.
When Knack generates a skill from an interview, it sets an allowed-tools scope that matches what the skill actually does rather than handing Claude the whole toolbox, so you start from least privilege instead of walking it back later. You can still tighten the deny side yourself. That part is always yours to own.