Most OpenClaw agents get their superpowers from third-party skills. The trade-off is obvious: every extra line of unvetted JavaScript now runs with the same authority as your agent, your Slack token, maybe even process.env.OPENAI_API_KEY. Last quarter Cisco Talos researchers caught a credential-harvesting skill masquerading as a “Google Drive summarizer”. Nobody wants to be the next headline.

Why Skill Security Matters (Ask Cisco Talos)

In August 2024 Cisco’s security team reverse-engineered twenty community skills. One, openclaw-gdocs-helper, quietly POSTed conversation transcripts to paste[.]audit-log[.]xyz. Less than 100 lines of obfuscated code siphoned private Slack DMs and OpenAI prompts. The author used a disposable GitHub account and got 97 stars before anyone noticed.

That incident forced us—and frankly the whole OpenClaw community—to admit our marketplace is closer to npm circa 2017 than Apple’s App Store. There is no mandatory review queue, no reproducible build system, no automated signing. You are the last line of defense. This guide shows how to audit a skill before the inevitable claw skill install.

Reading SKILL.md Like a Threat Model

Every skill is supposed to ship a top-level SKILL.md. Don’t skim it; treat it like you’d treat a new Terraform module headed for production.

Quick sanity checklist

  • Author identity: GitHub profile with real activity? LinkedIn or company domain? Disposable handles are a red flag.
  • Version tags: Look for semantic versions and release notes. Skills stuck at 0.0.1 for six months often break silently.
  • Changelog detail: Does the maintainer log security-relevant changes like scope narrowing or dependency bumps?
  • Dependencies: npm i tree should be short. A summarizer does not need puppeteer or aws-sdk.
  • Permissions declared: Good skills list required environment variables and external APIs upfront.
  • Telemetry: Opt-in analytics are fine. Hard-coded calls to amplitude.com in the code but absent from docs are not.

Red flags inside the markdown

Search for vague language:

  • “may send usage data” → ask what data and where
  • “requires admin OAuth scope” → why does a calendar reader need repo:write?
  • No LICENSE section → unknown legal status; harder to fork and patch if urgent

Bottom line: if the docs are sloppy, the code probably is too.

Static Scanning: VirusTotal, npm audit, and Your Own Grep

The ClawCloud CLI (>= 1.9.0) integrates with VirusTotal. Turn it on once; every subsequent claw skill install uploads the tarball hash and checks for known IOCs.

claw config set security.virustotal true # verify claw config get security

What the setting does:

  1. Computes SHA-256 of the exact zip served by the registry.
  2. Hits VirusTotal’s database with an /file/report?apikey=<org-scoped-token>.
  3. Blocks install if any engine (Dr.Web, Fortinet, etc.) flags it as malicious.

Limitations: VirusTotal only knows what others already caught. Zero-day backdoors sail right through.

Local static checks

I still run:

# inside a temp container npm ci --ignore-scripts npm audit --omit=dev

Plus a personal favorite: grepping for network calls outside allowed domains.

grep -R "http[s]*://" . | grep -vE "(api.openai.com|graph.microsoft.com)"

You’ll be amazed how many “simple” skills ship an auto-updater that pings a random S3 bucket every hour.

Sandboxing Untrusted Skills

Node 22 finally gave us experimental permission flags (--allow-fs-read, --allow-net). The OpenClaw daemon exposes those via claw skill sandbox.

# deny everything, then allow net access only to slack.com claw skill sandbox pdf-reader \ --deny-all \ --allow-net=slack.com

Under the hood the daemon spawns each skill in its own Worker using node --experimental-permission. It’s not bullet-proof—core modules can still abuse child_process—but it shuts the door on casual data leaks.

Docker for the Paranoid (or Regulated)

If you deploy on your own metal instead of ClawCloud SaaS, wrap the entire agent in a minimal Docker image. Run skills with:

--network=none --read-only --cap-drop=ALL

and mount only the sockets you actually need, e.g. /run/user/1000/claw.sock. Yes, this is slower. Yes, it keeps compliance happy.

Reviewing the permissions.json Manifest

Since Gateway v0.18 every skill can (optionally) declare a permissions.json next to package.json. The spec is blunt:

{
  "fs": ["read:/tmp/cache"],
  "net": ["https://api.github.com", "smtp://mail.example.com:587"],
  "env": ["OPENAI_API_KEY"],
  "shell": false
}

If the file is missing, the daemon currently defaults to all permissions. That’s a debate on GitHub #982 and hopefully changes soon. Meanwhile you can require an explicit manifest via:

claw config set security.requirePermissionManifest true

Expect skill authors to screw this up. I’ve seen manifests that whitelist net: ["*"] because the author thought it meant “all HTTPs domains are okay”. That defeats the purpose. Push a PR or file an issue; most maintainers will fix it when nudged.

Mapping permissions to risk

  • fs write » potential ransomware behavior, especially if path is /
  • net * » data exfiltration, cryptojacking
  • env ALL » credential leaks; force a subset
  • shell true » remote-code heaven for an attacker

Be ruthless. If a PDF parser wants shell:true, walk away.

The Community Vetting Process (Spoiler: It’s Mostly You)

The harsh truth: there is no formal OpenClaw review board. The #skills Discord channel plus a handful of Github Actions tests are all we have. That said, a few community norms reduce risk:

  1. Signed tags: Many top skills push GPG-signed git tags. If the latest tag suddenly isn’t signed, hold off.
  2. PR reviewers: Skills with ≥ 2 mandatory reviewers catch most obvious shenanigans. Look at branch protection rules.
  3. Reverse bounty channel: Maintainers sometimes post PayPal bounties for anyone who finds security flaws.

But again, none of this is enforced. The marketplace currently lists ~1,300 skills; maybe 150 get regular eyes on them. Until a foundation grows up around OpenClaw, you cannot outsource due diligence.

Hardening Checklist Before claw skill install

  • Read SKILL.md; verify author, scopes, dependencies.
  • Static scan: claw --virustotal, npm audit, grep network calls.
  • Require permissions.json; refuse if missing.
  • Sandbox with Node permission flags or Docker.
  • Use env vars scoped to the skill, not global secrets.
  • Monitor outbound traffic from the daemon (nethogs, iptables --log).
  • Pin version numbers; no ^ in your skill.json.
  • Subscribe to the GitHub repository’s security advisories.
  • Consider self-hosting Sentry to catch unexpected exceptions fast.

Yes, it’s work. But so are incident response write-ups and customer apology emails.

Next Step: Automate the Boring Parts

Start by dropping this into your CI pipeline. It blocks pull requests that bump any skill without passing the checks described above.

# .github/workflows/skill-audit.yml
name: Skill Audit
on:
  pull_request:
    paths:
      - "skills/**"
jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install ClawCloud CLI
        run: npm i -g @clawcloud/cli@1.9.0
      - name: Run VirusTotal scan
        run: claw skill audit --all --virustotal
      - name: Check permission manifests
        run: claw skill audit --require-permissions

Merge blocks are annoying until the day they save you from shipping a keylogger. Set it up once and forget it.

That’s it. Your agent can keep learning new tricks without leaking your entire Slack history to some burner domain. Stay paranoid and happy hacking.