vet-skills

One command between your agent and anything it installs. Verdicts come from KillerSkills; the policy is yours or your organization's.

Install

Node 20 or newer. The package is a single file with no dependencies.

❯ npm i -g vet-skills
❯ vet-skills --version
0.1.0

Hook into Claude Code

The hook registers a PreToolUse entry in ~/.claude/settings.json (merged, idempotent). From then on every npx skills add, claude plugin install and claude mcp add the agent runs is checked first. Blocked installs exit with the reason so the agent sees it; sandboxed and observed installs proceed with a notice.

❯ vet-skills hook install claude-code
✓ Claude Code hook installed (~/.claude/settings.json)
Every skills add / plugin install / mcp add is now checked against policy personal.

Other agents: run vet-skills install <skill> instead of npx skills add, or call vet-skills check from your own hook — it exits non-zero on block.

Check a skill

check resolves the skill to a specific version and artifact hash, fetches the current verdict, and evaluates it against your policy — without installing anything.

karim@mbp — ~/work/acme-api
❯ vet-skills check pdf-tools-pro
Resolving [email protected] from skills.sh …
vet-skills 0.1.0 · policy acme/default-strict · cached verdict (18m)
CAUTION 61/100 [email protected] · docforge · 241K installs
Observed in sandbox (3 scenarios, 41s):
✓ network api.pdf.co only — matches declaration
✓ memory no writes
! filesystem reads ~/Downloads/* beyond project scope
! supply depends on pdf-lib@* (unpinned)
Policy acme/default-strict:
✓ min score 50 61 ≥ 50
! filesystem scope requires approval outside project
→ sandbox: install with filesystem restricted to ./
Full report: https://killerskills.ai/skills/skills_sh/pdf-tools-pro/0.9.2

Every verdict page shows the same findings with the recorded syscall and network trace, so a reviewer can see exactly what the skill did in the honeypot.

Decisions

DecisionWhat happens
allowInstall proceeds. Verified skill, or caution within policy.
sandboxInstall proceeds with restrictions (filesystem scoped to the project, declared hosts only). Default for CAUTION under the strict policy.
approval_requiredThe CLI offers [s]andboxed · [n]o · [r]eport (and [y]es when you are on the personal policy). In an org, the request lands on the Approvals page for an approver; once granted, the next install of that version is allowed.
blockInstall refused, with the last safe version named when there is one.
deferUnscored version: the sandbox runs it first (30–60s), then one of the decisions above applies.
observeOrg enforcement is off, or the trial has ended. The decision is logged but nothing is blocked.

Verdict API unreachable? The personal policy fails open with a warning; org policies choose offline_action (allow or block).

Join an organization

An org admin gets an enroll token from the dashboard's Onboarding page. Joining replaces your personal policy with the org's, and from then on each install decision is reported to the org's inventory and audit log.

❯ vet-skills join acme --token ks_org_…
✓ Enrolled this machine in acme as a.chen (policy acme/default-strict v3)
❯ vet-skills status
org acme · agent ag_01J… · claude_code on mbp
policy acme/default-strict v3 · enforce
last report 2 minutes ago · 14 installs tracked
cache 38 verdicts · 1.2 MB
❯ vet-skills leave
✓ Left acme. Back to the personal policy.

Admins can invite teammates by email from the Developers page; invitees sign in and run the same join command.

Detonate your own skill

Publishing a skill? Upload a local directory and get the same honeypot verdict the registry crawl produces, before anyone installs it. The bundle is tar'd (excluding node_modules and .git) and run in an isolated sandbox with decoy credentials and a recording egress proxy.

❯ vet-skills detonate ./my-skill --publisher cyligence
Uploading my-skill (84 KB) …
✓ static analysis 0.8s · 0 findings
✓ prompt integrity 1.1s · clean
✓ scenario 1/3 setup 11s · no network
✓ scenario 2/3 task 17s · api.example.com only
✓ scenario 3/3 adversarial 22s · no credential reads
VERIFIED 93/100 [email protected]
Report: https://killerskills.ai/skills/private/my-skill/0.3.0

Free accounts get 20 detonations a day. The sandbox never has your real credentials: every secret in it is a tagged decoy, so any exfiltration attempt is attributable to the run.

Personal policy

Without an org, vet-skills uses the personal policy: minimum score 50, caution allowed, unknown versions detonated first, credential reads and undeclared egress blocked. Change it with a YAML file:

policy.yaml
# vet-skills policy set policy.yaml
name: mine
min_score: 60
caution_action: sandbox # allow | sandbox | approval | block
unknown_action: detonate # detonate | block | allow
behavior:
credential_reads: block
undeclared_egress: block
memory_writes: block
tool_shadowing: block
fs_outside_project: approval
unpinned_deps: warn
publishers:
allow: [anthropic, github, stripe]
block: []
block_younger_than_days: 30
❯ vet-skills policy set policy.yaml
✓ policy mine v1 active
❯ vet-skills block sketchy-helper --reason "phones home"
✓ sketchy-helper added to the personal block list

Command reference

CommandPurpose
check <skill>Dry-run the decision for a skill, plugin or MCP server (name, name@version, or registry URL).
install <skill>Check, then run `npx skills add` if allowed.
detonate <path> [--publisher h]Upload a local bundle to the sandbox and print its verdict.
why <skill>The last decision for this skill and the policy rule behind it.
join <org> --token <t> [--email you@co]Enroll this machine in an organization.
leaveBack to the personal policy.
policy show | set <file>View or replace the local policy (YAML).
block <skill> [--reason]Add to the personal block list.
statusOrg, policy version, last report, cache size.
hook install claude-codeRegister the Claude Code PreToolUse hook.
hook evalCalled by the agent: reads hook JSON on stdin, exits 2 to block.

Global flags: --json for machine-readable output, --agent to override the detected agent, -h, -v.

What leaves your machine

vet-skills sends the skill name, version and artifact hash to resolve a verdict. When enrolled in an org it also reports each decision (skill, version, hash, outcome, restrictions) plus the agent type and hostname so the inventory and audit log are accurate. It never uploads file contents, prompts, environment variables or source code — the only upload path is detonate, and only for the directory you point it at. See Security and Privacy.