Skills
There is no skills field in any of the three request surfaces. Nothing in the
Anthropic Messages API, the OpenAI Responses API or Chat Completions carries a
list of an agent’s skills.
That is worth saying first, because it bounds everything below.
What the firewall can see
A dispatching tool. Claude Code exposes skills through a tool named Skill,
whose input schema enumerates the available skill names. The firewall reads that
enum and records each name — marked inferred, because it is a read of a
schema’s shape rather than of a documented field. A client that presents skills
differently produces nothing here.
An invocation. When a skill actually runs, it appears in the replayed
conversation as a tool_use block naming the dispatcher and the skill:
{ "type": "tool_use", "name": "Skill", "input": { "skill": "deploy" } }
That is exact. Those rows are recorded as invoked, and it is the one place
skills are visible as fact rather than as a guess.
The deterministic control
If you need certainty, do not govern the skill. Govern the tool that dispatches it:
vulnetix ai-firewall policy guardrail no-skills \
--rule-type tool_deny --action strip --pattern 'Skill' \
--priority 100 --enable
strip removes the dispatcher from the request. Without it the model has no route
to any skill, whatever the schema said. This is a real boundary, it costs
granularity, and it is honest about which it is.
Skill rules
skill_deny and skill_allow match against the names above:
vulnetix ai-firewall policy guardrail no-deploy-skill \
--rule-type skill_deny --action block --pattern 'deploy' \
--priority 100 --enable
They accept block and flag only. strip is rejected, and that rejection is
deliberate: a skill is a value inside another tool’s schema, so there is nothing to
remove from a request array. Accepting strip would give you a rule that stored
cleanly, showed as enabled in the dashboard, and enforced nothing — the failure
this whole product treats as worse than an outage.
If a strip reaches the engine on a skill rule anyway, it is escalated to block
rather than silently skipped.
What to actually do
For most organisations the useful posture is:
- Run with no skill rules and read the inventory for a fortnight.
- If skills appear that should not, and the set is stable, write
skill_denyrules atflag, thenblock. - If you need a hard guarantee rather than a good control, strip the
Skilltool and accept that you have removed the feature.
Treat skill rules as advisory-grade. They are built on a convention, that convention will change as clients evolve, and this page will say so when it does.
Related
- Tool rules — the deterministic route.
- The inventory — what
declared,invokedandinferredmean. - Limitations — the honest list for this whole section.