OWASP Agentic Skills Top 10 compliance
Scan the agentic skills installed in your workspace — the SKILL.md
instruction bundles, .cursor/rules, .windsurf/rules, AGENTS.md, and their
scripts/metadata — against the OWASP Agentic Skills Top 10 (AST01–AST10), and
generate a compliance report.
TL;DR
bashgadriel code scan # skills pillar runs automaticallygadriel code report --compliance owasp-agentic-skills --pdf
What are "agentic skills"?
A skill is a reusable bundle an AI coding agent discovers, loads, and executes
with the agent's own permissions: natural-language instructions (SKILL.md),
executable helpers, resources, and metadata. Because a skill runs in the host
agent's security context, a malicious or careless skill has the agent's full
blast radius — its credentials, its filesystem, its network.
The OWASP Agentic Skills Top 10 catalogues that risk. Gadriel is a static scanner for it: no code leaves your machine, no skill is executed, and semantic checks (when enabled) borrow the host agent's own LLM rather than calling out to a vendor model.
The ten controls (AST01–AST10)
| ID | Risk | Severity | In one line |
|---|---|---|---|
| AST01 | Malicious Skills | Critical | Hidden payloads — in code and in SKILL.md prose. |
| AST02 | Supply Chain Compromise | Critical | No provenance; nested deps and repo-config files carry the payload. |
| AST03 | Over-Privileged Skills | High | No permission manifest, or one nobody enforces. |
| AST04 | Insecure Metadata | High | Frontmatter is attacker-controlled input parsed unsafely — deceives the installer and runs on load. |
| AST05 | Untrusted External Instructions | High | Skills fetch mutable external docs and consume them as instructions. Rug-pullable. |
| AST06 | Weak Isolation | High | Skills run in the agent's context; sandboxing is optional and off by default. |
| AST07 | Update Drift | Medium | No immutable pinning; auto-update applies unverified upstream changes mid-session. |
| AST08 | Poor Scanning | Medium | Prose+code+metadata format evades pattern matching; scanners get bypassed. |
| AST09 | No Governance | Medium | No inventory, approval, audit trail, or revocation — "shadow AI." |
| AST10 | Cross-Platform Reuse | Medium | Security metadata doesn't survive porting between runtimes. |
Scanning skills
The skills pillar runs as part of a normal scan:
bashgadriel code scan # all pillars, including skillsgadriel code scan . skills # skills pillar only (fast)
Or use the dedicated skills surface for focused work:
bashgadriel code skills list # inventory table of every discovered skillgadriel code skills scan # skills-specific scan outputgadriel code skills show <id> # full record: permissions, references, findings, coveragegadriel code skills refs # reverse index of external instruction referencesgadriel code skills diff a b # diff two skill manifests / platform snapshotsgadriel code skills normalize <id> # emit a Universal Skill Format (USF) manifest
Skill findings appear in .security/findings.json with a SKILL-AST<nn>-<NNN>
rule id (e.g. SKILL-AST01-002) and a CODE-W<pillar>-SKILL-<NNN> finding id,
alongside every other pillar.
What gets discovered
By default Gadriel discovers skills across six platform layouts:
claude · cursor · windsurf · copilot · codex · generic
Discovery looks for .claude/skills/*/SKILL.md, .cursor/rules/*.mdc,
.windsurf/rules/*.md, AGENTS.md, and the other platform conventions. A skill
directory must sit under a recognised path (e.g. a skills/ segment) to be
inventoried — see Troubleshooting if a library comes back empty.
Generating the compliance report
bash# Markdown (default) + HTMLgadriel code report --compliance owasp-agentic-skills# Add the typst PDFgadriel code report --compliance owasp-agentic-skills --pdf# All frameworks at once (this one included)gadriel code report --all-frameworks --pdf
Slug: the framework is owasp-agentic-skills. Do not confuse it with
owasp-agentic — that is the OWASP Agentic AI Top 10 (ASI01–ASI10), a
different framework about agent applications, not skills.
Output lands in .security/compliance/owasp-agentic-skills.{md,typ,pdf}. Each of
the 10 categories expands into sub-controls; assessable sub-controls are graded
from your scan findings, and administrative ones are marked for manual review.
Reading the verdict
Overall: PARTIAL — 1 of 3 assessable control(s) not fully satisfied; N require manual review
- PASS / PARTIAL / FAIL roll up the assessable sub-controls (those a static scan can grade from findings).
- "require manual review" counts the administrative sub-controls (signing infrastructure, approval workflow, isolation posture) that a static scan cannot verify — they are surfaced as not assessed, never silently passed.
The report exits non-zero (--fail-on verdict, the default) when the verdict is
PARTIAL/FAIL, so you can gate a build on it.
Governance: inventory, pin, approve, verify
AST07 (drift) and AST09 (governance) are about change control, not a one-time scan. Gadriel gives you a committed, reviewable governance surface:
bashgadriel code skills pin # write/refresh skills.lock (pin all discovered skills)gadriel code skills approve <id> # record a human approval into skills.lockgadriel code skills revoke <id> # revoke a previous approvalgadriel code skills verify # CI gate — see below
skills.lock is a plain file you commit and review in git — the audit trail AST09
asks for. gadriel code skills verify is the enforcement verb:
- exit 0 — every skill is pinned and approved
- exit 3 — a skill is unpinned, drifted, or unapproved (fail the build)
Status note: the verify / pin / approve governance verbs are the
runtime-enforcement half of the program and are still being wired end-to-end.
verify fails closed (exit 3) rather than passing silently, so it is safe to
put in CI today — it just won't yet clear on a fully-governed repo. Track
ADR-179/182 for the enforcement rollout.
Configuration (.gadriel.toml)
toml[skills]enabled = trueplatforms = ["claude", "cursor", "windsurf", "copilot", "codex", "generic"]extra_roots = [] # extra directories to search for skillsfollow_home = false # also scan ~/.claude/skills etc.max_skill_mb = 64 # skip pathologically large skill bundlesnl_analysis = true # natural-language (prose) instruction analysis[skills.references]fetch = "on-demand" # how external-instruction references are resolvedallow_hosts = [] # allowlist of hosts a skill may reference[skills.supply_chain]require_signature = falseapproved_publishers = [][skills.governance]require_approval = ["L2", "L3"] # risk tiers that need human approval
How Gadriel finds what pattern-matchers miss (AST08)
The OWASP evidence base (ClawHavoc, Snyk ToxicSkills, Trail of Bits) shows every
tested scanner has been bypassed — with 100,000 leading newlines to force
truncation, payloads hidden in .pyc/.docx, and prompt-injections aimed at the
scanner's own LLM judge. AST08 is therefore treated as a constraint on how the
other nine are built, not just a checkbox:
- Two-signal discipline — a malicious-skill finding requires more than one independent indicator, to resist a single obfuscation.
- Prose analysis — SKILL.md natural-language instructions are analysed, not just code, because the payload is often in the prose.
- Anti-evasion invariants — text is canonicalised (NFKC, zero-width/bidi/ homoglyph handling, encoded-payload decode) before it reaches any report, renderer, or Tier-2 prompt.
- Never-gate for AI verdicts — semantic (Tier-2) analysis routes through the host agent's own LLM and can only add advisory context; it can never gate a build on its own, so a prompt-injected judge can't turn a real finding off.
Constraints (by design)
Three limits are non-negotiable and shape what Gadriel can and cannot check:
| Constraint | Consequence |
|---|---|
| Static analysis only | No sandbox execution of skills; no runtime interception. Gadriel reasons about the skill, it does not run it. |
| Code never leaves the machine | No per-skill live registry/reputation lookups (that would leak your installed-skill inventory). Only bulk signed snapshots on a schedule. |
| No outbound LLM calls | Semantic analysis borrows the host agent's LLM (Tier-2, opt-in), never a Gadriel-owned model endpoint. |
CI recipe
yaml- name: Scan skillsrun: gadriel code scan . skills --fail-on high- name: Skills compliance reportrun: gadriel code report --compliance owasp-agentic-skills --pdf# Optional governance gate (fails until skills are pinned + approved)- name: Skills governance gaterun: gadriel code skills verifycontinue-on-error: true # while the enforcement half rolls out
Troubleshooting
| Symptom | Cause & fix |
|---|---|
skills missing from scan_types_run, empty skills.json | The skill library uses a repo-root layout the discovery doesn't recognise. Ensure skills sit under a skills/ path segment, or add the directory to [skills] extra_roots. |
Report says Overall: PASS — 0/0 assessable | No skill findings mapped to assessable controls. Confirm skills were discovered (gadriel code skills list) and that your scan produced SKILL-AST* findings. |
skills verify exits 3 on a repo you consider clean | Expected until you pin + approve your skills into skills.lock, and while the enforcement half is being wired. |
| Wrong framework in the report | Use --compliance owasp-agentic-skills, not owasp-agentic (that's the Agentic AI Top 10). |
See also
gadriel code skills --helpandgadriel code report --help- ADR-169 — the Agentic Skill Security program charter and AST01–AST10 coverage map
- ADR-170…182 — the per-control detection design (metadata, permissions, supply chain, references, isolation, anti-evasion, governance, USF)
- ADR-181 — OWASP Agentic Skills Top 10 as a compliance framework
