Skip to main content

Command Palette

Search for a command to run...

My agent will run whatever I hand it, so I looked into Chainguard Skills to make it secure

Updated
8 min readView as Markdown
C
I'm a Staff Solutions Architect at Chainguard, where I help teams adopt secure software supply chains. My career spans from early '90s networking through modern DevSecOps, container security, and AI implementations. Break Glass Notes is where I write about the practical gaps I hit in the field — the questions dashboards can't answer, the feeds that don't exist, and the tooling I end up building to fill them. Expect posts on container images, SBOMs, FIPS compliance, CVE tooling, and the occasional deep dive into registry APIs.

I spend most of my week helping teams lock down what runs in their build pipelines. Base images, libraries, CI actions. Lately the question I get asked has shifted: what about the skills my coding agent is loading?

It is a fair question, and for most teams the honest answer right now is "nobody is checking."

The thing nobody put a gate in front of

An agent skill is a folder with a SKILL.md in it. Some frontmatter, some Markdown instructions, occasionally a script or two. That is the whole artifact. It is trivially easy to publish and trivially easy to install, which is exactly why there are tens of thousands of them.

The problem is what happens after you install one. A skill does not run in a sandbox. It runs with whatever permissions your agent already has: your repo, your shell, your credentials, your session. It is closer to a sudo alias than to an npm package.

Attackers noticed before most of us did.

  • Snyk's ToxicSkills audit scanned 3,984 skills from ClawHub and skills.sh in early February 2026 and found security flaws in 36% of them, including 1,467 vulnerable skills and live malicious payloads aimed at OpenClaw, Claude Code and Cursor users. (Snyk)

  • Trend Micro documented the Atomic macOS Stealer being delivered as a skill. Malicious instructions sat inside SKILL.md and used the agent as the trusted middleman to talk the human into typing their password into a fake setup prompt. (Trend Micro)

  • Unit 42 spent February to May 2026 looking at ClawHub after it had wired in VirusTotal and ClawScan, and still found five live malicious skills. One of them, omnicogg, hid an AMOS dropper in a README.md and padded the file with roughly 22 MB of junk so scanners would skip it. Both scanners returned a clean verdict. (Unit 42)

That last one is the part I keep coming back to. Scanning happened. Scanning passed. The skill was still malware.

What I actually do about it now

Chainguard publishes a public registry of hardened skills at skills.cgr.dev/public, over a thousand of the most popular community skills, re-ingested and re-hardened continuously. It is pull-only and it needs a Chainguard account but no entitlement, so you can try it on a laptop this afternoon. You need chainctl v0.2.282 or later.

Browsing it looks like this:

chainctl auth login
chainctl skills list --group public/github.com/github/awesome-copilot
 TYPE  | NAME                    | LATEST TAG | UPDATED
-------|-------------------------|------------|------------
 skill | agent-supply-chain      | latest     | 5 days ago
 skill | codeql                  | latest     | 5 days ago
 skill | game-engine             | latest     | 5 days ago
 skill | mcp-security-audit      | latest     | 5 days ago
 skill | multi-stage-dockerfile  | latest     | 5 days ago

Public skills are namespaced by where they came from, public/<host>/<owner>/<repo>/<name>, so provenance is in the path itself. Before installing anything I pull it to a directory and read it:

chainctl skills pull \
  skills.cgr.dev/public/github.com/github/awesome-copilot/game-engine:latest \
  ./game-engine

Every hardened skill carries a HARDENING.md that pins the upstream repo, the exact commit that was hardened, the outcome of the run, and whether the SKILL.md was modified. The per-model fix plans and the reconciled synthesis get recorded alongside it, so the diff is auditable rather than a trust-me verdict.

When I am happy with it:

chainctl skills install \
  skills.cgr.dev/public/github.com/github/awesome-copilot/game-engine:latest
Installing github.com/github/awesome-copilot/game-engine
 AGENT       | LOCATION                        | MODE
-------------|---------------------------------|----------
 Claude Code | .claude/skills/public-github...  | symlink

It detects the agents on the machine and drops a shared canonical copy into .agents/skills/ with per-agent symlinks. No new toolchain, no CI wiring. chainctl skills uninstall <install-name> takes it back out.

A real finding, and it is not malware

The example I use in customer conversations is deliberately unglamorous. It is add-educational-comments, a perfectly legitimate skill from GitHub's awesome-copilot repo that reads your code and adds explanatory comments to it.

The hardening engine flagged it high severity under a rule called minimal-permissions. The reasoning, paraphrased from the report: the skill's job is to statically analyse files and comment on them, so it never needs to execute the code. The prompt's language about not breaking execution is a constraint on the output, not a licence to run things. The hardened version drops the implied permission to execute.

Nobody wrote that skill with bad intent. There is no payload, no C2, no obfuscation. It simply asked for more reach than its job required, the way almost all of these do, because the author was writing instructions for a model and not a security policy. Then a prompt injection lands in a file the skill is reading, and that unnecessary execute reach is the difference between a weird comment and a shell.

This is why I think "is it malicious?" is the wrong first question. Most of the risk is over-permissioning in skills written by people acting in good faith. Signature scanning does not see that at all.

How the hardening works

The pipeline is close to what Chainguard already does for containers and libraries, applied to a new artifact type:

  1. Ingest. Skills are pulled from community registries, starting with skills.sh, with more sources added over time.

  2. Evaluate. Deterministic and agentic checks run against a ruleset built from open source intelligence and Chainguard's own research. It targets over-permissioning, obfuscated commands, base64 execution, credential harvesting, untrusted download domains, unrestricted shell access, and vague descriptions that let a skill be invoked when it should not be.

  3. Fix, not just flag. This is the part that matters to me. An agent applies one fix at a time and commits each change individually, so every published skill links back to a pull request with a full diff.

  4. Publish with provenance. The artifact ships as OCI with the upstream commit pinned and the HARDENING.md audit log attached.

  5. Reconcile continuously. It is a loop, not a one-time scan. Upstream changes or a new rule means affected skills are re-evaluated and re-hardened, so the catalog does not rot.

The other two doors

If you want your agent to discover skills live instead of installing them, there is an MCP server serving the same hardened catalog:

claude mcp add --transport http --scope user cgr-skills https://skills.cgr.dev/mcp

Run /mcp in a session, pick cgr-skills, authenticate in the browser.

And if the skills you worry about are your own internal ones, there is a private Skills Registry that stores them as OCI artifacts at skills.cgr.dev/<your-org>/<name>:<tag>, managed with the same chainctl skills verbs. That one deserves its own post, and it is the one I am writing next.

What this does not do

I would rather be straight about the limits.

Hardening is not a sandbox. A hardened skill still runs with your agent's permissions, and a tightly scoped skill pointed at a hostile repo is still reading hostile input. The rules catch known attack patterns, and the pattern list will keep growing because attackers keep inventing. Agent Skills is also still in beta, so expect the surface to move.

What it does change is the default. Right now the default is that a Markdown file from a stranger inherits your credentials and nobody looked at it. Pulling from a hardened, continuously reconciled catalog with an audit trail attached is a strictly better starting position than pulling from the open marketplace and hoping.

That is a low bar. We should clear it anyway.

Next up: the skills you wrote yourself

Everything above is about skills that came from strangers. In most of the conversations I have, that turns out to be the smaller half of the problem.

The bigger half is internal. The deploy skill someone wrote so the agent could push to staging. The incident-triage skill that reads your logging stack. The one that knows how to query the customer database. Nobody published those to a marketplace, so nobody applied a marketplace's scrutiny to them either, and they tend to carry far more reach than anything you would install from the public catalog. A minimal-permissions finding on a code-commenting skill is a rounding error next to an internal runbook that hands the agent production credentials because that was easiest at the time.

The Chainguard Skills Registry is the answer to that. Your skills become versioned OCI artifacts scoped to your organization, validated before they go up and pulled through the same install path as everything else. And they can run through the same Factory pipeline that hardens the public catalog, so your internal playbooks get the same ruleset, the same fixes, and the same audit trail rather than a one-time review that nobody repeats.

The next post is that walkthrough: enabling the registry, validating and pushing a skill, what the hardening pass actually changes on a real internal runbook, and how to keep the whole thing versioned instead of pasted into a wiki. If you want to read ahead, the docs are here: Getting started with the Chainguard Skills Registry.


References

M
Mateo Ruiz10h ago

The shift from “is this skill malicious?” to “does this skill have more permission than its job requires?” is the more important security model. A legitimate skill with unnecessary shell or credential access can become dangerous as soon as the agent processes untrusted input.

This is also where provenance and versioning become critical. In production AI work, including at IT Path Solutions, I’d want the skill version, upstream commit, effective permissions, and hardening changes tied to the agent run itself. Otherwise, when behavior changes, it’s difficult to tell whether the problem came from the model, the skill instructions, or a dependency update.

The other point worth emphasizing is that hardening and isolation solve different problems. Least privilege reduces blast radius, but it doesn’t make an agent safe to trust with arbitrary repositories. You still need execution boundaries, credential isolation, and an approval path for actions that cross those boundaries.

C

Agreed, and the run correlation point is the sharpest part of this. Right now the provenance stops at the artifact: upstream commit, hardening log, version tag, all in the OCI layer, none of it tied to the run that produced the weird output. That makes behavior drift hard to attribute.

Worth flagging that effective permissions do not exist as a field yet. A skill's real reach is whatever the agent grants plus whatever the instructions talk the model into. That is a gap to close rather than data to expose.

On isolation, same page. Hardening shrinks blast radius, it does not replace execution boundaries or an approval path.