← back to blog

How to secure skills?

Originally published on Medium

How I started thinking about agent skills as untrusted code, and the four things that would make one safe to run.

The trust gap between what a skill says and what it does

A few months ago I installed a skill for my coding agent the same way most people do. I read a one line description, decided it sounded useful, and let it run. It had access to my repository, my shell, my environment variables, and my cloud credentials, because that is just how skills work today. They inherit whatever the agent can reach.

Then it hit me that I had just done the one thing I spend my whole job telling other engineers not to do. I ran untrusted code with full privileges because the label looked friendly.

That is the entire security model of agent skills right now. A skill is a folder of instructions and sometimes scripts that you drop next to your agent to teach it a new trick. There is no install time review, no permission prompt, no runtime check that the skill does what its description says. You read the name, you trust the name, and the name is the only thing standing between a helpful formatter and something that quietly reads ~/.aws/credentials on its way out the door.

This post is the framework I landed on after sitting with that discomfort for a while. I want to walk through why the obvious fixes do not actually fix it, and then the four properties I think a skill needs before any of us should feel okay running it.

The problem is not malware. It is the gap.

Let me be precise about the threat, because "skills can be malicious" is both true and useless as a starting point.

The real issue is the distance between what a skill claims to do and what it can actually do. A skill describes itself in plain English at the top of a file. That description is marketing copy. It is not enforced by anything. The skill can say "formats your code" and also, in the same breath, read every file in your home directory and post them somewhere. Nothing in the system cross checks the claim against the behavior.

I started calling this the trust gap, and once you see it you cannot unsee it. Every other problem with skills is a flavor of this one gap.

And it is not hypothetical at small scale. In Palo Alto Networks Unit 42's 2026 audit of 49,943 community skills (Behavioral Integrity Verification, arXiv:2605.11770), 80% behaved differently from their declared behavior. The reassuring detail is also the unsettling one: about 81% of those deviations trace to plain developer oversight rather than malice, a skill that grew a feature and never updated its own description. But from a security standpoint, sloppy and malicious produce the same blast radius, because you trusted the description either way.

A signature proves who wrote it, not what it does

Why the obvious fixes do not close the gap

When I bring this up, the first answer is always the same. "Just sign them." Make authors cryptographically sign their skills, only run signed ones, done.

Signing is good. You should do it. But sit with what a signature actually proves. It proves who published the bytes and that the bytes did not change in transit. That is provenance. It is genuinely useful and I would not skip it.

It tells you exactly nothing about what the skill does.

A signature from a real author on a skill that quietly exfiltrates secrets is a perfectly valid signature on a malicious skill. You have cryptographic proof of who handed you the knife. Worse, signing can make things less safe in practice, because a green "verified" checkmark trains people to stop reading. We have run this exact experiment before with signed installers and signed browser extensions. Provenance and behavior are different questions, and signing only answers the first one.

The second answer is "scan them." Run a static analysis pass, look for dangerous patterns, block the bad ones. Also good, also worth doing. But a skill is mostly natural language instructions aimed at a model, not a binary with a fixed control flow. The dangerous behavior often is not in the skill's own code at all. It is in what the skill convinces the agent to do with the tools the agent already has. Static scanning of the skill file misses that, because the payload executes through the agent, not through the skill.

So signing answers "who," scanning answers "what does the file contain," and neither answers the question that actually matters: what will this thing do when it runs against my machine, and is that what it promised?

Four pillars

Here is where I landed. A skill becomes something I would actually trust when it has four properties, and importantly, when those four properties compose. No single one is enough. Together they turn a skill from "a name I chose to believe" into "a thing whose behavior I can check."

The four pillars of a trustworthy skill

Pillar 1: Stateful

Right now a skill is a floating blob. You do not really know which version you have, whether it changed since yesterday, or what changed. The first property is to give a skill an identity that is tied to its content.

Concretely: version it, and pin it by a hash of its contents. If even one byte of the skill changes, the hash changes, and that change becomes a visible event instead of a silent update. This solves the most boring and most common attack, which is not a skill that was malicious on day one. It is a skill you reviewed once, that updated itself quietly three weeks later into something you never agreed to.

The industry is already converging here. There are emerging proposals for a content addressable skill identity, where the identity of a skill is a deterministic hash over its normalized file tree, so the same skill always produces the same fingerprint regardless of how it was packaged. That fingerprint is the anchor everything else hangs off of. You cannot sign, eval, or attest a thing you cannot name, and "name" has to mean "exact contents," not "whatever the author called it this week."

One caution I want to flag, because I argued myself out of it. Stateful should mean versioned and pinned. It should not mean self updating and self modifying. A skill that rewrites itself at runtime is not stateful in a good way, it is just unauditable. Pin first, update deliberately.

Pillar 2: Eval-gated, without becoming the new attack surface

Before a skill runs against your real environment, it should have to prove it is safe in a sandbox. Stand it up in an isolated environment, run it through a battery of behavioral checks, and only promote it to "allowed" if it passes. This is just CI for trust.

The trap, and the reason I add the second half of that sentence, is that the evaluation harness is itself a place where untrusted skill code runs. If you are not careful, you build a beautiful gate and then hand the attacker a privileged sandbox with network access and your test fixtures in it. The skill that knows it is being evaluated can behave during the eval and misbehave in production, which is the oldest trick in the book.

So the eval has to run with less privilege than production, not more, and it has to assume the thing it is testing is hostile to the test itself. The point of the gate is to catch problems without becoming a problem. If your eval environment is more interesting to an attacker than your prod environment, you built it backwards.

Pillar 3: Signed and attested, with a capability manifest

Now signing earns its place, but with a crucial addition. Along with the signature, the skill ships a capability manifest. A short, machine readable declaration of what the skill is allowed to touch. May it read the repo? Write to it? Reach the network? Run a shell?

This is the move that makes signing useful for behavior and not just provenance. The signature now covers a specific, enforceable claim. The author is not just saying "I made this." They are saying "I made this, and it only does these things, and I am putting my name on that statement." It turns a vague description into a contract you can hold the skill to.

By itself a manifest is still just a promise. A well behaved author writes an honest one and an attacker writes a flattering one. Which is exactly why it needs the fourth pillar to mean anything.

Pillar 4: Runtime attestation, declared vs did

This is the one I care about most, because it is the only pillar that checks behavior at the moment behavior actually happens.

Everything so far happens before the skill runs. Versioning, eval, signing, the manifest. They are all predictions about what the skill will do. Runtime attestation is the part that watches what it actually does and compares it, live, against what it declared.

Runtime attestation compares the declared manifest against observed behavior

The mechanism is simpler than it sounds. You already have a natural checkpoint, which is the tool call boundary. Every time the skill drives the agent to read a file, write a file, run a command, or make a network call, that action passes through a place you control. So you sit at that boundary with the capability manifest in hand and you ask one question on every action: did the skill just declare it would do this?

The manifest said read repo and write repo, network none. At runtime you see it read the repo, fine, write the repo, fine, and then attempt a POST to some address it never declared. That last one is drift. Now you have a decision to make, and you can make it with actual evidence: allow what matches, flag what drifts, block what is both undeclared and dangerous.

This is the difference between trusting a promise and verifying it. The skill said it would never touch the network. At runtime, it tried. You caught it not because you guessed it was bad, but because what it did disagreed with what it said.

I want to be honest about the limits here, because I have seen this idea oversold. Runtime attestation catches execution that disagrees with the declaration. It does not catch a skill that declared a dangerous capability and then used it for a subtly bad purpose. If the manifest says "may write repo" and the skill writes a plausible but backdoored line of code, that is within its declared envelope, and this pillar will wave it through. Attestation is an accountability and drift layer, not a mind reader. It works best as the last line under the first three, not as a substitute for them.

How they fit together

The reason I keep saying these compose is that they map onto a skill's life, each covering a stage the others cannot.

Where each pillar lives in a skill's lifecycle

Provenance and identity get set early, when the skill is published. Pinning and the eval gate happen when you install it. And behavior, the thing you actually care about, can only ever be proven at the moment the skill runs. That last point is the whole argument in one line. Everything before runtime is a prediction. Only runtime is evidence.

Drop any one pillar and you can feel the hole. No statefulness, and a trusted skill silently mutates into an untrusted one. No eval, and you find out it is bad in production. No manifest, and you have nothing to compare runtime behavior against. No runtime attestation, and every claim you collected is just a claim.

Where I am taking this

I am building reference pieces of this, starting with the part that is most missing in practice, which is the runtime declared versus did check at the tool call boundary. The earlier pillars have real momentum behind them already, identity and signing especially. The runtime layer is where I think the interesting and underbuilt work is, partly because it is the hardest to get right without drowning developers in false positives.

If you run agents with skills today, the cheapest thing you can do this week is stop treating the description as truth. Pin your skills to a version. Write down, even informally, what each one is actually allowed to touch. And if you can put anything at all at the tool call boundary that notices when a skill does something it never mentioned, do that, because that is the one check nobody else is running for you.

The label is not the contract. The behavior is. Until we can check the behavior, every skill we install is a name we decided to believe.

I am a security engineer working on AI security, mostly around securing coding agents and the tooling that runs alongside them. If you are working on this too, I would genuinely like to compare notes.

Sources and further reading

  • Behavioral Integrity Verification for AI Agent Skills, Palo Alto Networks Unit 42, arXiv:2605.11770 (writeup)
  • Agent Skills in the Wild: an empirical study of security vulnerabilities at scale, arXiv:2601.10338
  • Benchmarking security risk detection in open agentic skill ecosystems, arXiv:2606.00925