SkillAgentSearch skills...

Stss

Skill Trust & Signing Service — security layer for AI agent skill ecosystems with cryptographic attestation, static scanning, and LLM-powered behavioral analysis

Install / Use

/learn @kenhuangus/Stss
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

STSS — Skill Trust & Signing Service

Cryptographic security for AI agent skill ecosystems. Scan, sign, and verify skills before they execute inside your AI agents.


What Is STSS?

Modern AI coding agents — Claude Code, OpenAI Codex, VS Code Copilot, OpenCode, OpenClaw — are becoming increasingly extensible through skills: packaged capabilities that agents can download and execute on your behalf. A skill might read files, call external APIs, run shell commands, or modify your codebase.

This extensibility is powerful. It is also a significant attack surface.

A malicious or compromised skill can:

  • Exfiltrate secrets by reading .env, ~/.aws/credentials, or SSH keys and sending them to a remote server
  • Execute arbitrary code through shell injection hidden deep in an import chain
  • Hijack the agent itself by embedding prompt injection or context-poisoning instructions in its SKILL.md documentation
  • Persist silently by running post_install.sh scripts that establish backdoors before the user ever sees output
  • Tamper undetected if there is no cryptographic record of what files were present when the skill was reviewed

STSS is the missing security layer between skill registries and skill execution. It treats every skill as untrusted code and requires proof — a cryptographically signed attestation — before that skill is allowed to load.


Why We Need STSS

The Supply Chain Problem for AI Skills

The npm and PyPI ecosystems learned this lesson the hard way: package managers that install and execute arbitrary code without verification are a persistent attack vector. The AI skill ecosystem is repeating this pattern at an accelerated pace, with two compounding factors:

  1. Skills run inside privileged agents. When an agent executes a skill, the skill inherits the agent's access to your filesystem, environment variables, API keys, and the ability to issue further prompts. The blast radius of a compromised skill is far larger than a compromised library.

  2. Skills can attack the agent itself. Beyond traditional code execution risks, skills can manipulate agent behavior through prompt injection embedded in documentation files — an attack vector that has no equivalent in traditional software supply chains.

The Threat Landscape

| Attack Vector | Example | Traditional Package Scanning | STSS | |---|---|---|---| | Shell execution | subprocess.run(["curl", ...]) in a helper module | Partial | Full (static + chain tracing) | | Credential theft | Reading ~/.aws/credentials | Partial | Full | | Prompt injection | "Ignore previous instructions" in SKILL.md | No | Yes | | Context poisoning | "You are now in debug mode" in docs | No | Yes | | Consent gap | post_install.sh that runs before the user is aware | No | Yes | | Import chain obfuscation | Innocent index.pyutils/helper.pycurl evil.com | No | Yes (chain tracer) | | Tampered skill | Files modified after signing | No | Yes (Merkle verification) | | Registry-flagged malware | Known-bad skill in skills.sh | No | Yes (registry adapter) | | Behavioral mismatch | "Markdown formatter" that exfiltrates data | No | Yes (LLM audit) |

STSS vs. Existing Tools

| Tool | What It Covers | What It Misses | |---|---|---| | npm audit / pip audit | Known CVEs in dependencies | Skill-specific threats, prompt injection, consent gaps | | Semgrep / Bandit | Code patterns in isolation | Cross-file chains, behavioral mismatch, LLM-specific attacks | | Socket / Snyk | Supply chain metadata | Skill documentation attacks, post-install consent gaps | | STSS | All of the above + AI-specific threats | — |

STSS does not replace these tools — it layers on top of them and adds the AI-specific threat categories that none of them address.


How STSS Is Implemented

Architecture Overview

  skill directory on disk
          │
          ▼
  ┌───────────────┐
  │   Ingestion   │  Walk files, apply .stssignore, never follow symlinks
  └───────┬───────┘
          │ FileEntry[]
          ▼
  ┌───────────────────────────────────────────────────────┐
  │                    Scan Pipeline                      │
  │                                                       │
  │  ┌─────────────────┐   ┌──────────────────────────┐  │
  │  │  RegexAdapter   │   │     SemgrepAdapter        │  │
  │  │  (default,      │   │  (if semgrep on PATH,     │  │
  │  │   zero deps)    │   │   falls back to regex)    │  │
  │  └────────┬────────┘   └────────────┬─────────────┘  │
  │           │                         │                 │
  │           └────────────┬────────────┘                 │
  │                        │ Finding[]                    │
  │           ┌────────────▼────────────┐                 │
  │           │     Hook Detector       │  consent_gap    │
  │           │  (install scripts,      │  findings       │
  │           │   manifest hooks)       │                 │
  │           └────────────┬────────────┘                 │
  │                        │                              │
  │           ┌────────────▼────────────┐                 │
  │           │     Chain Tracer        │  cross_file     │
  │           │  (Python/JS/TS/Shell    │  findings       │
  │           │   import graphs)        │                 │
  │           └────────────┬────────────┘                 │
  │                        │                              │
  │           ┌────────────▼────────────┐                 │
  │           │     Caterpillar        │  credential,    │
  │           │  (auto-detected,       │  exfiltration,  │
  │           │   free)                │  supply chain   │
  │           └────────────┬────────────┘  findings       │
  │                        │                              │
  │           ┌────────────▼────────────┐                 │
  │           │      LLM Auditor        │  behavioral,    │
  │           │  (Claude API, opt-in)   │  contextual     │
  │           └────────────┬────────────┘  findings       │
  │                        │                              │
  │           ┌────────────▼────────────┐                 │
  │           │    Registry Adapter     │  registry       │
  │           │  (skills.sh, opt-in)    │  findings       │
  │           └────────────┬────────────┘                 │
  └────────────────────────┼──────────────────────────────┘
                           │ All Finding[]
                           ▼
                  ┌─────────────────┐
                  │  Policy Engine  │  PASS / PASS_WITH_WARNINGS / FAIL
                  └────────┬────────┘
                           │
               ┌───────────┴──────────────┐
               │ PASS or PASS_WITH_WARNINGS│
               ▼                          │
      ┌─────────────────┐                 │ FAIL
      │   Merkle Tree   │                 ▼
      │  SHA-256, det.  │      skill quarantined
      │  PROMOTE strat. │      STSS_REPORT.md written
      └────────┬────────┘
               │ root hash
               ▼
      ┌─────────────────┐
      │  Ed25519 Signer │  signs canonical JSON of attestation payload
      └────────┬────────┘
               │
               ▼
        attestation.json   ←── stored alongside skill, checked at load time

Technology Stack

| Component | Technology | |---|---| | Language | TypeScript, strict mode throughout | | Package manager | pnpm workspaces | | Cryptography | @noble/ed25519 (Ed25519), Node.js built-in crypto (SHA-256) | | Validation | Zod — all external data validated before use, no unsafe casts | | Static scanning | Custom RegexAdapter (zero deps) + SemgrepAdapter (optional) + Caterpillar (auto-detected) | | Policy | YAML — js-yaml + Zod schema, supports snake_case and camelCase | | Ignore rules | ignore package (gitignore syntax) | | Shell analysis | shellcheck (if on PATH) with regex fallback | | LLM audit | Anthropic Claude API (opt-in) | | Registry | skills.sh API with 24h disk cache | | CLI | commander.js + chalk | | Testing | Vitest — 10 acceptance tests, all passing |

Core Modules

| Module | Responsibility | |---|---| | ingestion.ts | Recursive async dir walk; symlink-safe; .stssignore support | | merkle.ts | Deterministic SHA-256 Merkle tree; odd-node PROMOTE strategy; empty-tree constant | | scanner/regex-adapter.ts | 9-category pattern scanner; per-file, per-line, with escalation logic | | scanner/semgrep-adapter.ts | Shells out to semgrep; parses JSON output; falls back to regex | | hook-detector.ts | Finds install scripts by name and manifest reference; runs shellcheck/regex on their contents | | chain-tracer.ts | Builds import graph (Python/JS/TS/Shell); reverse BFS from finding to entry point | | caterpillar.ts | Auto-detects Caterpillar on PATH; shells out for credential theft, exfiltration, and supply chain findings; offline or authenticated mode | | policy.ts | Zod-validated YAML loader; neverSign / requireApproval / autoApprove decision logic | | llm-auditor.ts | Calls Claude API with structured audit context; maps response to Finding[] | | registry-adapters/skillssh.ts | Fetches skills.sh audit page; 24h TTL cache; synthetic CRITICAL on malicious flag | | signer.ts | Ed25519 sign over canonical JSON; key held in memory only during signing | | verifier.ts | Signature check → Merkle recompute → optional policy re-evaluation | | pipeline.ts | Orchestrates the full scan → sign flow |

Security Design Invariants

  • All file I/O is async — no blocking calls in the scan path
  • Merkle tree is 100% deterministic — identical files always produce the same root
  • Private keys are ephemeral — resolved from ref, used, and the reference is discarded
  • LLM and registry passes are non-blocking — any failure produces a warning; the scan always completes
  • **All external data is Zod-v
View on GitHub
GitHub Stars4
CategoryDevelopment
Updated17d ago
Forks1

Languages

TypeScript

Security Score

70/100

Audited on Mar 22, 2026

No findings