DEV Community

gevar
gevar

Posted on

One SKILL.md, every AI agent: I packaged my open-source security scanner as a portable skill

AI agents are turning into the most impatient users your tools will ever have. They don't read READMEs top to bottom, they don't hunt for flags, and they will guess wrong unless you tell them exactly what to do. The industry's answer in 2026 is the skill: a single SKILL.md file — YAML frontmatter plus instructions — that any compatible agent can load.

I maintain AttackSurfaceX, an open-source (MIT), deliberately non-destructive attack surface scanner. Packaging it as a skill took one file and a few careful decisions. Here's the whole thing, and why each part exists.

The skill, in full

---
name: asx-security-scan
description: "Run AttackSurfaceX (ASX), a safe non-destructive attack surface"
  scanner, against authorized targets. Use when the user asks to scan or audit
  a domain they own or are permitted to test...
---

# ASX Security Scan
[what the tool is, what it can NEVER do]

## When to use / Do NOT use
- owns-or-authorized targets only; no permission = no scan
- no exploitation, no fuzzing, no raising scan rates

## Setup / Usage / Interpreting results
- pipx install; always start with -p safe
- LOW = hardening gaps (give the exact header to add)
- if every port is "closed" and TLS always fails, say "geo-filtered", don't report TLS weakness

## Safety rules (never skip)
Enter fullscreen mode Exit fullscreen mode

That's it. One file. But four decisions in it are the actual point of this post.

Decision 1: Authorization is the first line of the skill, not a footer

An agent holding a scanner is one vague prompt away from scanning something it shouldn't. So the skill opens with a gate — owns or written authorization — and a hard "Do NOT use" list. Instructions beat intentions: agents follow structure, and the structure here says permission precedes execution.

Decision 2: Encode the tool's doctrine, not just its CLI

AttackSurfaceX is built so it physically cannot send state-changing requests. The skill repeats that doctrine in words, because an agent that understands why won't try to route around it. If your tool has a philosophy, write it into the skill — that's the difference between a wrapper and a capable operator.

Decision 3: Teach interpretation, or the agent will panic

A raw scanner dump scares users. The skill maps severities to plain language: LOW usually means hardening gaps with the exact header to add; INFO is context. It also carries two hard-won lessons from real runs:

  • SPA catch-alls return 200 for every path — judge by content variance, not status codes.
  • Geo-filtering looks exactly like TLS failure. If every port is "closed" from one network position, the honest output is "this target appears to be filtering your region" — not a CWE-326 report. False positives are reputation damage.

Decision 4: Deduplicate before you speak

Real-world runs showed the same finding arriving from a built-in module and a plugin, so the scanner now merges duplicates (Jaccard-similar titles, same CWE, same target). The skill tells the agent to read duplicates_suppressed so it never double-reports an issue.

Where it runs

The same file works across the current generation of agents — local coding agents and cloud/desktop agents alike — and the open skill hubs (skillsmp, skillsllm, lobehub) distribute exactly this format. In an agent that supports skills, you invoke it with a slash command, or the agent loads it automatically when the task matches its description.

Try it

pipx install git+https://github.com/gevarru/AttackSurfaceX.git
Enter fullscreen mode Exit fullscreen mode

The skill lives at skills/asx-security-scan/SKILL.md in the repo. Fork it, adapt the gates to your own tools, and publish yours — the best agent tooling this year is going to be small, honest markdown files like this one.

⭐ github.com/gevarru/AttackSurfaceX — MIT, Python 3.11+.

Top comments (0)