An open API service indexing awesome lists of open source software.

https://github.com/openclaw/clawscan

Composable security scanning harness for agent skills
https://github.com/openclaw/clawscan

agent-security ai-security llm-security prompt-injection security-scanner skill-scanner skills-security

Last synced: 14 days ago
JSON representation

Composable security scanning harness for agent skills

Awesome Lists containing this project

README

          

# ClawScan 📡

ClawScan is a composable security scanning harness for agent skills.

Run a suite of skill security scanners, pass the results to a judge harness, and compare against multiple skill security benchmarks.

[![CI](https://img.shields.io/badge/CI-passing-brightgreen)](https://github.com/openclaw/clawscan/actions/workflows/ci.yml?query=branch%3Amain)
[![Release](https://img.shields.io/badge/Release-passing-brightgreen)](https://github.com/openclaw/clawscan/actions/workflows/release.yml)
[![Latest release](https://img.shields.io/badge/latest%20release-unreleased-lightgrey)](https://github.com/openclaw/clawscan/releases)

## Quick Start

Install ClawScan:

```bash
npm install -g @openclaw/clawscan
```

Command-backed scanners and judges run in ClawScan's Docker runtime by default,
so keep Docker running for local scans.

Run NVIDIA SkillSpector and Cisco Skill Scanner against a local `skills/` folder:

```bash
clawscan --scanner skillspector --scanner cisco
```

## Scan a known malicious skill

This example scans Trail of Bits' [`csv-summarizer`](https://github.com/trailofbits/overtly-malicious-skills/tree/4ffbf9461ef0505f9ce76a0d3694a18ec33ea531/skills/csv-summarizer) skill, which claims to summarize a CSV file but also prints every environment variable when run.

```bash
git clone https://github.com/trailofbits/overtly-malicious-skills.git /tmp/overtly-malicious-skills
cd /tmp/overtly-malicious-skills
git checkout 4ffbf9461ef0505f9ce76a0d3694a18ec33ea531
clawscan skills/csv-summarizer \
--scanner skillspector \
--scanner cisco \
--output /tmp/clawscan-csv-summarizer.json
```

Sample findings:

```txt
targets: 1
scanner_completed: 2
scanner_failed: 0
scanner_skipped: 0
issues_found: 2
errors: 0
full_results: /tmp/clawscan-csv-summarizer.json
```

The results bundle keeps the top-level artifact plus per-scanner JSON reports.

Artifact excerpt

```json
{
"schemaVersion": "clawscan-run-v1",
"target": "skills/csv-summarizer",
"scanners": {
"cisco": {
"status": "completed",
"durationMs": 42,
"outputPath": "clawscan-csv-summarizer/skills/csv-summarizer/cisco.json",
"isSafe": true,
"maxSeverity": "SAFE",
"findingsCount": 0
},
"skillspector": {
"status": "completed",
"durationMs": 42,
"outputPath": "clawscan-csv-summarizer/skills/csv-summarizer/skillspector.json",
"severity": "MEDIUM",
"score": 31,
"recommendation": "CAUTION",
"issues": [
{
"id": "LP3",
"severity": "MEDIUM",
"file": "SKILL.md"
},
{
"id": "E2",
"severity": "HIGH",
"file": "scripts/summarize.py"
}
]
}
}
}
```

## Motivation

Agent-skill security is new and fast-moving, with researchers and companies
exploring many promising scanners, datasets, and judge harnesses. In our
[ClawHub Security Signals paper](https://arxiv.org/html/2606.01494v1), we found
that combining multiple scanners with a configurable judge works better than
relying on any single scanner.

ClawScan turns that approach into a repeatable CLI. It includes a built-in `clawhub` profile, a saved scanner-and-judge configuration that matches what ClawHub runs in production, so researchers can reproduce results, test improvements, and help improve detection against the weekly refreshed ClawHub security-signals dataset.

## Commands

| Command family | Use |
| --- | --- |
| `clawscan --scanner ` | Run one or more scanners against an explicit target. Omit `` to scan child skill directories under `./skills`. |
| `clawscan scanners [list\|]` | Discover supported scanner IDs, required env vars, upstream links, descriptions, and install guidance. |
| `clawscan profiles [-v]` | Inspect built-in plus nearest project-local profiles; `-v` prints the resolved profile catalog as YAML. |
| `clawscan benchmark [list\|]` | Discover or run supported benchmarks through a selected scanner/profile/judge setup. |
| `clawscan install [...]` | Install or verify local scanner dependencies where ClawScan has registry-backed install plans. |

## Scanners

`--scanner` selects a scanner adapter to run, writes its raw JSON evidence into
the results artifact, and can be repeated to compare multiple scanners in one
run:

```bash
clawscan ./my-skill \
--scanner skillspector \
--scanner cisco
```

Discover the scanner catalog from the CLI:

```bash
clawscan scanners
clawscan scanners skillspector
```

### Available scanners

> **Want to add your scanner to the list?** Follow the guide in [docs/scanners.md](docs/scanners.md#adding-a-built-in-scanner-adapter)

| ID | Name | Repo | Description | Required env vars | Local dependency setup |
| --- | --- | --- | --- | --- | --- |
| `agentverus` | AgentVerus | [repo](https://github.com/agentverus/agentverus-scanner) | Local file or directory scanner invoked through agentverus-scanner. | none | `npm install --save-dev agentverus-scanner` |
| `aig` | Tencent AI-Infra-Guard | [repo](https://github.com/Tencent/AI-Infra-Guard) | API-backed MCP Server & Agent Skills scan through a running local or private A.I.G service. Upstream defaults to `http://localhost:8088` and currently lacks built-in authentication, so do not expose it on public networks. | none
Optional configAIG_BASE_URL, AIG_API_KEY, AIG_MODEL, AIG_MODEL_API_KEY, AIG_MODEL_BASE_URL, AIG_USERNAME, AIG_SCAN_LANGUAGE, AIG_SCAN_PROMPT, AIG_SCAN_THREAD_COUNT, AIG_POLL_INTERVAL_MS, AIG_POLL_MAX_ATTEMPTS.

AIG_BASE_URL defaults to http://localhost:8088; upstream model config is optional and can fall back to the A.I.G service defaults. | run the A.I.G Docker/API service separately |
| `cisco` | Cisco AI Defense skill-scanner | [repo](https://github.com/cisco-ai-defense/skill-scanner) | Local file or directory scanner invoked through `skill-scanner` with JSON report output. Optional upstream env vars enable LLM, VirusTotal, and Cisco AI Defense analyzers. | none
Optional configSKILL_SCANNER_LLM_API_KEY, SKILL_SCANNER_LLM_PROVIDER, SKILL_SCANNER_LLM_MODEL, SKILL_SCANNER_LLM_BASE_URL, SKILL_SCANNER_LLM_USER, SKILL_SCANNER_LLM_API_VERSION, SKILL_SCANNER_LLM_FORCE_JSON_OBJECT, SKILL_SCANNER_META_LLM_API_KEY, SKILL_SCANNER_META_LLM_MODEL, SKILL_SCANNER_META_LLM_BASE_URL, SKILL_SCANNER_META_LLM_API_VERSION, AWS_PROFILE, AWS_REGION, GOOGLE_APPLICATION_CREDENTIALS, VIRUSTOTAL_API_KEY, AI_DEFENSE_API_KEY, AI_DEFENSE_API_URL. | `uv pip install cisco-ai-skill-scanner` |
| `clawscan-static` | ClawScan Static | [repo](https://github.com/openclaw/clawscan) | Built-in deterministic text scanner for high-signal risky skill patterns. | none | skipped; built in |
| `skillspector` | NVIDIA SkillSpector | [repo](https://github.com/NVIDIA/skillspector) | Local file or directory scanner. Uses LLM mode when provider env vars are set; otherwise runs with `--no-llm`. | none
Optional configSKILLSPECTOR_PROVIDER, SKILLSPECTOR_MODEL, SKILLSPECTOR_MODEL_REGISTRY, SKILLSPECTOR_LOG_LEVEL, SKILLSPECTOR_SSL_VERIFY, NVIDIA_INFERENCE_KEY, OPENAI_API_KEY, OPENAI_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_PROXY_ENDPOINT_URL, ANTHROPIC_PROXY_API_KEY, ANTHROPIC_PROXY_API_VERSION. | `uv tool install git+https://github.com/NVIDIA/skillspector.git` |
| `snyk` | Snyk Agent Scan | [repo](https://github.com/snyk/agent-scan) | Local skill scanner invoked through `uvx snyk-agent-scan`. | `SNYK_TOKEN` | verifies `uvx` launcher |
| `socket` | Socket CLI | [repo](https://github.com/SocketDev/socket-cli) | Local file or directory scanner using Socket's public CLI full-scan path. | `SOCKET_CLI_API_TOKEN` | `npm install -g socket` |
| `virustotal` | VirusTotal API | [docs](https://docs.virustotal.com/reference/file) | API-backed single local file hash lookup. Directories return a skipped result. | `VIRUSTOTAL_API_KEY` | skipped; API-backed |

## Sandbox

ClawScan runs command-backed scanners and judges in
`ghcr.io/openclaw/clawscan-runtime:latest` by default:

```bash
clawscan ./my-skill --scanner skillspector
```

Use `--sandbox off` only in an already-isolated environment, or when you have
installed scanner dependencies on the host with `clawscan install`. Use
`--sandbox-env ` or a profile `sandbox.env` list to pass judge-specific
environment variables into the container.

## Judge Harness

`--judge` hands scanner evidence to an external agent command so it can inspect
the skill, do its own research in the scan workspace, and write a final JSON
verdict:

```bash
clawscan ./my-skill \
--scanner skillspector \
--judge 'codex exec --cd {{ workspace }} --output-last-message {{ output }} - < {{ prompt:./prompt.md }}'
```

Supported `--judge` placeholders:

| Placeholder | Meaning |
| --- | --- |
| `{{ workspace }}` | Temporary directory containing the copied skill, scanner JSON, and metadata. |
| `{{ prompt }}` | Render `./prompt.md` and pass the rendered prompt file path. |
| `{{ prompt: }}` | Render a specific prompt template and pass that file path. |
| `{{ output_schema }}` | Copy `./schema.json` into the workspace and pass that file path. |
| `{{ output_schema: }}` | Copy a specific schema file and pass that file path. |
| `{{ output }}` | File path where the judge should write its final JSON object. |

## Profiles

`--profile` runs a saved scanner and judge configuration, such as the built-in
`clawhub` profile that matches ClawHub's production scanner suite and Codex
judge harness:

```bash
clawscan ./my-skill --profile clawhub
```

Inspect the resolved profile catalog, including the nearest project
`.clawscan.yml` / `.clawscan.yaml` when present:

```bash
clawscan profiles
clawscan profiles -v
```

### Available profiles

| Profile | Scanners | Judge |
| --- | --- | --- |
| `clawhub` | `skillspector`, `clawscan-static` | Codex `gpt-5.5`, high reasoning, bundled ClawHub prompt/schema |
| `skills-sh` | `socket`, `snyk` (Gen Agent Trust Hub also runs on skills.sh but does not offer a CLI) | none |

### Build a custom profile with `.clawscan.yml`

Custom profiles can be created in `.clawscan.yml`.

This is useful for version controlling iterations on your profile, creating multiple profiles to run over the same skills, etc

```yaml
version: 1
profiles:
review:
scanners:
- skillspector
- snyk
sandbox:
env:
- OPENAI_API_KEY
- CODEX_API_KEY
judge:
command: >
codex exec --cd {{ workspace }}
--model gpt-5.5
--output-last-message {{ output }}
- < {{ prompt:./prompt.md }}
```

## Benchmarks

`clawscan benchmark ` runs a supported benchmark through the
selected scanners and optional judge harness:

```bash
clawscan benchmark list

clawscan benchmark SkillTrustBench \
--profile clawhub \
--output ./artifacts/skilltrustbench-clawhub.json
```

### Available benchmarks

| Benchmark | ID | Source |
| --- | --- | --- |
| ClawHub Security Signals | `clawhub-security-signals` | [Hugging Face](https://huggingface.co/datasets/OpenClaw/clawhub-security-signals) |
| SkillTrustBench | `SkillTrustBench` | [Hugging Face](https://huggingface.co/datasets/cuhk-zhuque/SkillTrustBench) |

### Submitting a patch to the `clawhub` profile

If you are a security researcher who found malicious skills live on ClawHub and
want to improve the production scanner so it catches them, use GitHub private
vulnerability reporting for the sensitive details and open a PR containing only
a candidate `proposals//clawscan.yml` config. For a guided walkthrough,
ask Codex:

```text
Use $report-clawhub-malicious-skill to walk me through reporting a malicious ClawHub skill.
```

### ClawHub Profile Benchmark

Profile: `clawhub`
Benchmark: pending maintainer `SkillTrustBench Profile Gate` run.
Artifact: uploaded by the workflow as `skilltrustbench-candidate`.