Sigstore-signed attestations for AI agent skills.
Variants don't ship. Signal does.
The agent-skills supply chain is the next attack surface. Pruner produces a portable, signed trust artefact that travels with every release tag.
Detection: cisco-ai-skill-scanner. Policy: coroboros. Signature: Sigstore.
- What Pruner is
- Why a wrapper, not another scanner
- Code inside skills
- What Pruner is not
- Why now
- Quick start
- Compared to
- Reports and verification
- Coverage
- Snyk second opinion
- Vision
- Governance
- License
A composite GitHub Action that runs at the publisher's CI before a skill release ships. It produces a single trust artefact: report-v1.json plus a CycloneDX SBOM and SLSA build provenance. The bundle is signed with public-good Sigstore and GitHub OIDC, and attached to every release tag. Consumers verify with gh attestation verify; no Coroboros service sits in the trust path.
Output is deterministic at v0.1. No LLM keys, no telemetry.
cisco-ai-defense/skill-scanner is the OSS reference engine for skill scanning — Apache-2.0, fully local, thirteen-pass static analyser plus bytecode, behavioural dataflow, meta-analyser, optional LLM-as-judge. Rebuilding it costs a year and yields a worse outcome. Pruner pins it as the detection backend and adds the four things it does not surface as discrete signals:
- agentskills.io frontmatter conformance (
FC001–FC005) — kebab-case names, description length, custom-fields-under-metadata, the Coroboros house rule againstmetadata.version(skill versioning is repo-tag-driven), and SPDX licence validation. - Identity-file write protection (
PI-IDFILE-001) — scripts that write toAGENTS.md,MEMORY.md,SOUL.md,~/.bashrc,.cursorrules,.claude/settings.json,CLAUDE.md. The ClawHavoc session-persistent backdoor pattern. - PEP-723 inline-deps unpinned (
PI-PEP723-001), markdown-image data-exfil (PI-MDIMG-001), webhook exfil (PI-EXFIL-001), remote-fetch-and-execute (PI-EXFIL-002), allowed-tools-vs-script mismatch (PI-PERM-001) — the supply-chain and permissions families documented in the OWASP Agentic Skills Top 10 and the Maloyan / Namiot SoK (arXiv:2601.17548). - Unicode codepoint families as named rules (
PI-UNI-001Tag block,PI-UNI-002variation selectors,PI-UNI-003bidi override,PI-UNI-004homoglyph instruction tokens,PI-UNI-005zero-width clusters) — Cisco catches these internally; Pruner exposes each as a discrete, OWASP-mapped signal that downstream consumers can audit independently.
The novel contribution is the trust artefact, not the scanner. The scanner is intentionally swappable — docs/why-cisco.md documents the swap path. The artefact spec (report-v1 + SBOM + in-toto attestations) is what travels with the skill.
Skill repositories ship code under scripts/ — shell, Python, JS, TS. Cisco's subprocess analyses all of it: Python AST, JS / TS, bash pipeline-analyser with taint flow, bytecode disassembly, Office macros, PDF structural. Pruner does not re-implement bandit, ruff, semgrep, or shellcheck.
The Coroboros pack adds patterns Cisco does not surface as discrete rules. Codepoint scans, frontmatter validators, PEP-723 metadata, identity-file path matching, webhook / tunnel signatures, remote-fetch-and-execute, and the cross-file allowed-tools-vs-scripts mismatch. The split is deliberate — Cisco's engine is the SAST surface, the Coroboros pack is the skill-specific posture surface.
- Not a runtime guard. Pruner runs at the publisher's CI, not inside a loaded agent. For consumer-side runtime auditing, see
affaan-m/agentshield(MIT, TypeScript, three-agent Opus pipeline that audits.claude/config, MCP servers, and hooks). Anthropic and skills.sh provide the install-time audit hook. - Not a live red-team tool. Probing a deployed agent with adversarial prompts is the job of NVIDIA garak, promptfoo, or Microsoft PyRIT. Those tools require a runnable agent endpoint; many skill repos ship none.
- Not a proprietary cloud-uplinked engine. Cisco runs fully local; Pruner runs fully offline by default.
snyk/agent-scanis a strong scanner but requiresSNYK_TOKENand uplinks scan content to Snyk cloud — incompatible with air-gapped or regulated workflows. Pruner accepts it as an opt-in second opinion (see Snyk second opinion).
The agent-skills ecosystem moved from launch (October 2025) to "registry already poisoned at scale" in four months. Snyk's ToxicSkills audit (February 2026) found 36.82 % of 3,984 scanned skills carrying security flaws and 13.4 % critical issues. The ClawHavoc campaign (Antiy CERT, Koi Security, January–February 2026) placed 1,184 malicious skills across the ecosystem with single-IP C2. Cato CTRL weaponised Anthropic's official slack-gif-creator skill in December 2025. Minor edits triggered a remote-fetch-and-execute that delivered MedusaLocker — under a single user-consent trust model.
Vendor responsibility lands on the user. Anthropic states explicitly: "It is the user's responsibility to only use and execute trusted Skills." Skills.sh runs a server-side audit at install through the CLI. A direct git clone bypasses it entirely. Once a skill is installed, drift is not re-scanned. The trust signal needs to live where the audit happens — at source, before publication.
Drop this into .github/workflows/pruner.yml. Replace <VERSION> with the latest tag from https://github.com/ob-aion/pruner/releases/latest (the latest badge at the top of this page points at the same place).
name: Pruner
on:
pull_request:
push:
tags: ['[0-9]+.[0-9]+.[0-9]+']
schedule:
- cron: '0 6 * * 1'
permissions:
contents: read
security-events: write
id-token: write
attestations: write
jobs:
audit:
uses: ob-aion/pruner/.github/workflows/scan.yml@<VERSION>
with:
fail-on: medium
skill-pattern: 'skills/*/SKILL.md'Templates for minimal and full integrations live in templates/. Consumer integration walkthrough: docs/consumer-integration.md.
Each tool answers a different question.
| Tool | Form | Where it runs | License | Network |
|---|---|---|---|---|
| Pruner (this repo) | composite GitHub Action | publisher CI | Apache-2.0 | offline by default |
cisco-ai-defense/skill-scanner |
CLI + reusable workflow | local or CI | Apache-2.0 | offline (LLM keys optional) |
snyk/agent-scan |
CLI | local + Snyk cloud | Apache-2.0 | SNYK_TOKEN required |
affaan-m/agentshield |
CLI + GitHub Action + plugin | consumer agent setup | MIT | ANTHROPIC_API_KEY for deep analysis |
| skills.sh audit (Gen ATH × Socket × Snyk) | server-side, via npx skills add |
install time | mixed (closed + commercial) | required |
Pruner answers "is this skill safe to ship?" — and produces a portable, signed answer that travels with the release tag. AgentShield answers "is this agent setup safe to load?" The static scanners answer "what does deep code analysis say about this artefact?" The skills.sh audit answers "is this safe to install through the registry CLI?" — and is bypassed by git clone.
Every release attaches pruner-report.zip to its GitHub release page. Inside: report-v1.json, aggregated SARIF, CycloneDX SBOM, OpenSSF Scorecard JSON, in-toto attestations, badge SVG. Verification:
gh release download <tag> --repo <owner>/<repo> --pattern 'pruner-report.zip'
gh attestation verify pruner-report.zip --owner <owner>Walkthrough: docs/verify-a-report.md. Schemas at schema/ — JSON Schema 2020-12.
Coverage matrix — what Cisco catches × what the Coroboros pack adds × what nothing covers: docs/coverage-matrix.md. FP-audit on anthropics/skills, vercel-labs/agent-skills, and coroboros/agent-skills: docs/fp-audit.md. Threat model and disclosure: docs/threat-model.md.
Optional. Set with-snyk: true and provide SNYK_TOKEN; Snyk findings land in the report's tools[] block with mode: second-opinion, blocking: false. Without a token the step is silently skipped. Setup walkthrough: docs/consumer-integration.md#snyk-second-opinion. Read the network-egress trade-off in docs/why-cisco.md#considered-alternatives before enabling.
The trust artefact is the deliverable; the scanner is replaceable. At 1.0: submit report-v1 and the attestation bundle shape as a candidate spec contribution to the OpenSSF Working Group on Supply-Chain Integrity. Register Pruner in the Sigstore landscape alongside.
The publisher-boundary placement closes two gaps that runtime guards and install-time audits cannot reach. First: direct git-clone of a skill repository bypasses any registry-side audit. Second: once a skill is installed, post-publish drift is never re-scanned.
Apache-2.0. Solo maintainer at v0.x; bus factor declared in BUS_FACTOR.md. Rule-pack and release policy: GOVERNANCE.md. Threat model and disclosure: SECURITY.md. Contributing: CONTRIBUTING.md.
Apache-2.0. See LICENSE.