How do I scan an OpenClaw skill for malware?
Option 1: the command line
Ironheights needs Node.js 20 or newer. Download or clone the skill to a folder, without installing it into your agent yet, and run:
npx ironheights scan ./path/to/skill
The scanner walks the folder within its limits, reads each file as text, and matches it against published rules. It never executes a file and does not extract archives; a bundled archive or executable is a finding on its own. To scan every skill already installed in the usual OpenClaw locations, use npx ironheights scan --all.
For automation, add --json or --sarif results.sarif for a report and --fail-on high to fail a CI job. Exit codes are 0 for no findings, 1 for review, 2 for block and 3 for an incomplete scan, where a file was skipped.
Option 2: the browser
If you do not want to install anything, paste a SKILL.md or drop a skill folder into the browser scanner. It runs the same content rules as the CLI inside your browser. The in-browser scanner never sends your skill's content anywhere; with your consent, the site records only the scan verdict. It cannot run the integrity checks, which need the CLI on your machine.
Reading the result
- block: at least one critical finding, or a score of 80 or more. Do not install until you understand every finding.
- review: at least one high or medium finding, or a score of 15 or more. A person should read the findings; some are false positives, such as documentation that mentions
sudo. - no-findings: no rule matched.
Each finding links to a rule. For example, IH-EXEC-001 is remote content piped into an interpreter, and IH-NET-001 is a network host outside the allowlist. The rules reference explains each one in plain language.
Before you scan
Scan a copy of the skill in a folder of its own, not a skill that your agent has already loaded. Scanning does not run anything, so it is safe to point it at a suspicious folder, but installing the skill first would let the agent read it before you have.
What a scan cannot see
A scan only sees what is in the files. If the skill links to a website that hosts the real command, you see a link finding, not the payload. Files larger than 1 MiB are skipped by default. The CLI names each skipped file and directory, reports the verdict incomplete and exits with code 3 (--allow-skipped accepts them), and the browser scanner shows "Incomplete scan". The skipped file itself is still not checked. Runtime behavior and novel phrasing are out of reach. See what Ironheights does not detect and the limitations page, and pair the scan with the 10-minute checklist.
Sources
- Ironheights README, GitHub.
- Ironheights rule reference (docs/rules.md), GitHub.
- ironheights on npm, npm.