Claude Code Reserved Two Skill Namespaces, and the Reason Is a Wildcard That Matched Too Much
Why Skill(anthropic-skills:*) stopped being a safe thing to write, and what that says about every allow rule that matches on a name
Claude Code lets you write one line in a settings file, Skill(anthropic-skills:*), and allow every skill your claude.ai account syncs down without a prompt. It reads like a rule about trust. It is actually a rule about spelling.
Version 2.1.282, published to npm on September 24 at 15:56 UTC, changed what that line matches. The changelog entry is nine words long in substance: those allow rules now "cover only skills synced from claude.ai, not plugins or other skills that merely use such a name." Read that backwards and you have the bug. Before 2.1.282, a plugin could use such a name.
Where a skill's command name comes from
Claude Code's own documentation lays out the naming rule in a table, and the table is the whole story.
A skill living at ~/.claude/skills/deploy-staging/SKILL.md or .claude/skills/deploy-staging/SKILL.md gets its command name from the directory name. It becomes /deploy-staging. The frontmatter name field is only a display label in that case.
A skill inside a plugin gets its command name from the frontmatter name or the directory name, "namespaced by plugin." The documented example is my-plugin/skills/review/SKILL.md becoming /my-plugin:review.
A skill synced from claude.ai gets "the skill's name on your claude.ai account, prefixed with anthropic-skills:." An account skill called deploy becomes /anthropic-skills:deploy.
Two different origins, one shared shape. The prefix before the colon is the plugin's name for a plugin skill and the literal string anthropic-skills for an account skill. Nothing in that scheme reserved the string. A plugin directory named anthropic-skills produced skills addressed as anthropic-skills:whatever, which is byte-for-byte what the account sync produces.
Now add the matching rule. Claude Code documents Skill(name) as an exact match and Skill(name *) as "prefix match with any arguments." An allow rule written over a namespace is a prefix match, and a prefix match cannot see where a skill came from. It sees a string.
So Skill(anthropic-skills:*) in your user settings meant: allow anything whose command name starts with anthropic-skills:. You wrote it thinking about the skills you enabled on your own account. It also covered a plugin in the last repository you cloned, if that plugin happened to be named the right thing.
The fix is three entries, and they all say the same thing
Version 2.1.282 does not patch the matcher. It reserves the namespace, in three places at once.
Allow rules of the form Skill(anthropic-skills:*) and Skill(claude-ai:*) now cover only skills synced from claude.ai. Skill folders, command files and workflow commands in either namespace no longer load at all, and the changelog notes that "a plugin so named still loads but yields name ties to synced skills." MCP servers configured under the name anthropic-skills or claude-ai now list no skills and no prompts, though their tools still work, and the fix is to rename the server in your MCP configuration.
Three surfaces, because there were three ways to write into that namespace. A skill directory, a plugin manifest, an MCP server. The pattern in the fix is worth more than the fix: whoever wrote it went looking for every producer of names in that space rather than hardening the one that got reported.
The sibling bug in the same release
One entry down, 2.1.282 also fixed "repository, user and --add-dir skills, commands and skills-directory plugin manifests pre-approving their own tools via allowed-tools under managed allowManagedPermissionRulesOnly."
The allowed-tools field is documented plainly. It "grants permission for the listed tools during the turn that invokes the skill, so Claude can use them without prompting you for approval." The grant clears when you send your next message. That is a sensible feature for a skill you wrote. It is a different thing entirely for a SKILL.md that arrived in a repository, because the file that asks for the permission is also the file that grants it.
allowManagedPermissionRulesOnly exists to stop exactly that. It is documented as making managed settings "the only settings source of permission rules," and its scope in the settings reference is Managed only, meaning an administrator sets it and a developer cannot. Until 2.1.282, a skill file's own allowed-tools line slipped past it.
Same bug class as the namespace. Content that the agent reads was allowed to describe itself into a permission it had not been given.
Why the settings precedence table is the thing to read
Claude Code's documented precedence runs managed settings first, then the command line (claude --settings), then project local (.claude/settings.local.json), then shared project (.claude/settings.json), then user (~/.claude/settings.json). Highest wins.
That order is the security model, and 2.1.282 spends most of its config-related entries enforcing it against things that were routing around it.
Project and local settings now ignore OpenTelemetry variables that turn on export, set the endpoint, or capture content, naming CLAUDE_CODE_ENABLE_TELEMETRY and OTEL_LOG_* directly. A repository can no longer switch on content capture for a session just by shipping a settings file. This one applies to every install, with no managed-settings gate, and the same release adds a startup notice plus /status and claude doctor entries listing which telemetry variables in a project's settings files were ignored or turned telemetry off.
sandbox.excludedCommands from project and local settings now gets ignored when managed settings or a --settings flag set allowUnsandboxedCommands: false, or when managed settings set allowManagedDomainsOnly: true. The settings reference marks sandbox.excludedCommands and allowUnsandboxedCommands as settable in any file while allowManagedDomainsOnly is Managed only, which is why the lock has to come from above.
And on Windows and WSL, a managed policy that exists but is invalid or unreadable now blocks user-writable HKCU and /etc/claude-code from applying. A broken policy used to fail open. It now fails closed.
Put this into practice
The lowest-friction thing you can do takes about a minute and requires no decisions.
Upgrade to 2.1.282 or later, then open a repository you did not write and read the startup notice. It now names telemetry variables in that project's settings files that were ignored or that turned telemetry off. claude doctor and /status carry the same list. You are unlikely to find anything. The point is that you now have a place to look, for a class of file most people have never opened.
Then grep your own settings for namespace-shaped allow rules:
grep -rn "Skill(" ~/.claude/settings.json .claude/settings.json .claude/settings.local.json
Any rule ending in :* is a prefix match. For the two reserved namespaces you are now covered. For every other prefix, including your own plugin names, you are not. If you allowed Skill(acme-tools:*) because your team ships a plugin called acme-tools, nothing stops a different acme-tools from existing in a repository you clone. Replace prefix rules with exact Skill(name) rules wherever the list of skills is short enough to enumerate, and accept the extra lines.
Third, audit allowed-tools in any skill you did not write. Open every SKILL.md under .claude/skills/ in repositories you cloned and read the frontmatter. You are looking for a Bash(...) grant on a skill you have no reason to trust.
The transferable rule is one question, and it applies well outside Claude Code. For every allow rule in your system that matches on a name, ask who can choose that name. If the answer includes anything that arrives with a git clone, the rule is a suggestion.
What this article does not establish
I did not reproduce the collision. I have not built a plugin named anthropic-skills on 2.1.281 and watched a Skill(anthropic-skills:*) rule cover it. The before-state described here is inferred from the changelog's own wording, which says the rules now cover only synced skills "not plugins or other skills that merely use such a name." That phrasing is specific enough to be load-bearing, but it is Anthropic describing its own fix, not a reproduction.
Anthropic published no advisory, CVE or exploitation report alongside the release. The changelog does not say whether this was found internally or reported from outside, and I could not determine which. Treat the absence of an advisory as an absence of information rather than as evidence that nothing was exploitable.
I also do not know how common Skill(anthropic-skills:*) is in real settings files. It is not a rule most people would write by hand, and the exposure depends entirely on how many did. The documentation I read describes current documented behavior, so the naming table quoted above reflects 2.1.282 and later, not what shipped in 2.1.281.
One thing genuinely limits the blast radius, and it is worth stating because it cuts against my own framing: the allowed-tools grant is documented as turn-scoped and clearing when you send your next message. A skill that pre-approved its own tools got one turn, not a standing permission. I did not measure that boundary, and a single turn is plenty for a Bash call.
The part worth keeping
Naming is a permission system whether you designed it that way or not. Claude Code had three separate producers writing into one name space and one matcher that read only the string, and the fix was to decide that the string belongs to one of them.
Go look at your own allow rules this afternoon. Not because a plugin named anthropic-skills is coming for you, but because you will probably find at least one wildcard you wrote while thinking about a set of things you controlled, matching a space you do not.
Sources: Claude Code CHANGELOG, 2.1.282 · npm publish record · Agent Skills documentation · Settings files and precedence · Settings reference
Medium metadata
- Title: Claude Code Reserved Two Skill Namespaces, and the Reason Is a Wildcard That Matched Too Much
- Subtitle: Why
Skill(anthropic-skills:*)stopped being a safe thing to write, and what that says about every allow rule that matches on a name - Tags: Claude Code, AI Agents, Developer Tools, Security, Software Engineering
- Canonical: import from the fervorai.dev URL