{"id":51261149,"url":"https://github.com/adudley78/clean-skill","last_synced_at":"2026-06-29T12:01:31.914Z","repository":{"id":352869428,"uuid":"1216988076","full_name":"adudley78/clean-skill","owner":"adudley78","description":"Detect malicious AI skills in skills marketplaces: platform-agnostic ingestion, YAML rule engine, secret scanner, LLM-as-judge, and a gVisor Docker sandbox for dynamic analysis.","archived":false,"fork":false,"pushed_at":"2026-04-21T12:44:16.000Z","size":86,"stargazers_count":0,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T14:39:57.124Z","etag":null,"topics":["ai-security","cli","llm","mcp","prompt-injection","python","sandbox","security","supply-chain-security","yara"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adudley78.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":"THREAT_MODEL.md","audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-21T12:38:21.000Z","updated_at":"2026-04-21T12:43:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/adudley78/clean-skill","commit_stats":null,"previous_names":["adudley78/clean-skill"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/adudley78/clean-skill","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adudley78%2Fclean-skill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adudley78%2Fclean-skill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adudley78%2Fclean-skill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adudley78%2Fclean-skill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adudley78","download_url":"https://codeload.github.com/adudley78/clean-skill/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adudley78%2Fclean-skill/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34925718,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-security","cli","llm","mcp","prompt-injection","python","sandbox","security","supply-chain-security","yara"],"created_at":"2026-06-29T12:01:29.117Z","updated_at":"2026-06-29T12:01:31.892Z","avatar_url":"https://github.com/adudley78.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# clean-skill\n\n**clean-skill** is an open-source scanner that detects malicious AI skills\nhiding in skills marketplaces. Threat actors are embedding prompt injection,\ndata exfiltration payloads, and host-compromise logic inside AI agent\nskills — the npm supply-chain problem, but for LLM agents. clean-skill scans\nskills **before** they are installed or executed.\n\nIt is platform-agnostic: Claude / Anthropic SKILL.md, MCP servers, OpenAI GPT\nActions, LangChain tools, AutoGPT plugins, OpenClaw/ClawHub skills, and any\ngeneric JSON/YAML tool manifest.\n\n## Why another scanner?\n\n| Tool                                   | Multi-platform | Crawler | Community rules | Dynamic sandbox | License |\n|----------------------------------------|:--------------:|:-------:|:---------------:|:---------------:|---------|\n| cisco-ai-defense/skill-scanner         | MCP only       | no      | yes             | no              | OSS     |\n| NMitchem/SkillScan                     | single         | no      | limited         | yes             | OSS     |\n| Mondoo                                 | no             | no      | no              | yes             | closed  |\n| Bitdefender AI Skills Checker          | OpenClaw only  | no      | no              | no              | closed  |\n| **clean-skill**                        | **all**        | **yes** | **yes**         | **yes**         | Apache-2 |\n\n## Install\n\nRequires Python 3.11+. Dynamic analysis requires Docker; gVisor (`runsc`)\nis preferred but the analyzer transparently falls back to `runc` with a\nwarning when gVisor isn't installed. Static analysis works without a\ncontainer runtime at all.\n\n```bash\ngit clone https://github.com/adudley78/clean-skill \u0026\u0026 cd clean-skill\npython -m venv .venv \u0026\u0026 source .venv/bin/activate\nmake install\ncp .env.example .env.local    # fill in API keys for LLM-as-judge\n```\n\nBuild the sandbox image (only needed for `--dynamic` or `make sandbox-test`):\n\n```bash\nmake sandbox-build\n```\n\nThe Makefile auto-detects Docker Desktop on macOS (CLI inside the .app\nbundle and the per-user socket at `~/.docker/run/docker.sock`), so the\ndynamic pipeline works without setting `DOCKER_HOST` by hand.\n\n## Quickstart\n\n```bash\n# Static-only scan of a local skill directory\nclean-skill scan --static-only tests/fixtures/skills/malicious_claude\n\n# Full scan: static + dynamic sandbox\nclean-skill scan tests/fixtures/skills/malicious_claude\n\n# Scan a remote manifest URL\nclean-skill scan https://example.com/some-skill/mcp.json\n\n# Emit a machine-readable report\nclean-skill scan --json tests/fixtures/skills/benign_claude \u003e report.json\n\n# List loaded detection rules\nclean-skill rules list\n```\n\nExit codes: `0` = clean, `1` = suspicious, `3` = malicious / block, `2` =\ningestion error. This makes clean-skill CI-friendly out of the box.\n\n## Architecture\n\n```mermaid\nflowchart LR\n    subgraph Ingestion\n        A[path / URL] --\u003e B{platform detector}\n        B --\u003e C1[Claude parser]\n        B --\u003e C2[MCP parser]\n        B --\u003e C3[OpenAI parser]\n        B --\u003e C4[LangChain parser]\n        B --\u003e C5[AutoGPT parser]\n        B --\u003e C6[OpenClaw parser]\n        B --\u003e C7[Generic JSON/YAML]\n        C1 \u0026 C2 \u0026 C3 \u0026 C4 \u0026 C5 \u0026 C6 \u0026 C7 --\u003e S[Skill model]\n    end\n\n    S --\u003e ST[Static Analyzer]\n    S --\u003e DY[Dynamic Analyzer]\n\n    subgraph Static\n        ST --\u003e R[YAML rule engine]\n        ST --\u003e K[Secret scanner]\n        ST --\u003e J[LLM-as-judge]\n    end\n\n    subgraph Dynamic\n        DY --\u003e SB[gVisor sandbox]\n        SB --\u003e MO[Mock LLM + audit log]\n        MO --\u003e BE[Behavioral scorer]\n    end\n\n    R \u0026 K \u0026 J \u0026 BE --\u003e F[Findings]\n    F --\u003e V[Verdict aggregator]\n    V --\u003e OUT[ScanReport]\n\n    subgraph Proactive\n        CR[Marketplace crawler] --\u003e Q[RQ queue]\n        Q --\u003e ST\n        OUT --\u003e TI[(Threat-intel DB)]\n    end\n```\n\nDetailed design in [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md).\n\n## Detection rules\n\nRules are YAML files under `rules/`. They are Sigma-inspired and open to\ncommunity contribution — see [`docs/rule_format.md`](./docs/rule_format.md)\nand [`CONTRIBUTING.md`](./CONTRIBUTING.md).\n\nStarter rule pack:\n\n| ID          | Category             | Severity | Signal                                         |\n|-------------|----------------------|----------|------------------------------------------------|\n| CS-PI-001   | instruction_override | high     | \"ignore previous instructions\" family          |\n| CS-PI-002   | prompt_injection     | critical | Fake `\u003csystem\u003e` role markup                    |\n| CS-OB-001   | obfuscation          | high     | Base64 blobs decoding to shell / URL / ELF     |\n| CS-EX-001   | exfiltration         | critical | webhook.site, requestbin, Slack/Discord hooks  |\n| CS-CH-001   | credential_harvest   | critical | `.aws/credentials`, `id_rsa`, IMDS, env dumps  |\n\n## Threat model\n\nDocumented in [`THREAT_MODEL.md`](./THREAT_MODEL.md). In short, clean-skill\naddresses five attack classes: prompt injection, obfuscated payloads,\noutbound exfiltration, credential / host-data theft, and sandbox escape via\ntool abuse.\n\n## Database migrations\n\nclean-skill uses [Alembic](https://alembic.sqlalchemy.org/) for schema migrations against\nthe threat-intel PostgreSQL store. Set the database URL before running any migration command:\n\n```bash\nexport CLEAN_SKILL_DB_URL=postgresql+psycopg://user:pass@localhost/cleanskill\n```\n\nApply all pending migrations:\n\n```bash\nalembic upgrade head\n# or: make migrate\n```\n\nGenerate a new migration after changing models in `src/clean_skill/threat_intel/db.py`:\n\n```bash\nalembic revision --autogenerate -m \"describe your change\"\n# or: make migration msg=\"describe your change\"\n```\n\n\u003e **Note:** Migrations run automatically at FastAPI startup. If `CLEAN_SKILL_DB_URL` is\n\u003e not set, startup skips migrations and logs a warning — the API still starts normally for\n\u003e environments without a database (e.g. CI static-analysis runs).\n\n## Project status\n\nv0.1 is an engineering preview. The static analyzer and CLI are stable enough\nto run in CI. The crawler and threat-intel API are scaffolded but intended\nfor the first few external contributors to extend.\n\n## License\n\nApache-2.0. See [`LICENSE`](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadudley78%2Fclean-skill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadudley78%2Fclean-skill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadudley78%2Fclean-skill/lists"}