$npx -y skills add prompt-security/clawsec --skill clawsec-suiteClawSec suite manager with embedded advisory-feed monitoring, cryptographic signature verification, approval-gated malicious-skill response, and guided setup for additional security skills.
| 1 | # ClawSec Suite |
| 2 | |
| 3 | ## Vercel Skills Installation |
| 4 | |
| 5 | Install with the Vercel Skills CLI for this harness: |
| 6 | |
| 7 | ```bash |
| 8 | npx skills add prompt-security/clawsec --skill clawsec-suite -a openclaw -y |
| 9 | ``` |
| 10 | |
| 11 | ## Operational Notes |
| 12 | |
| 13 | - Required runtime: `node`, `npx`, `openclaw`, `curl`, `jq`, `shasum`, `openssl`, `unzip` |
| 14 | - Side effects: setup scripts install an advisory hook under `~/.openclaw/hooks`, optionally create an unattended `openclaw cron` job, and use `npx clawhub@latest install` for guarded installs |
| 15 | - Network behavior: fetches signed advisory feed artifacts and remote catalog metadata unless you pin local paths |
| 16 | - Trust model: the suite can recommend removal or block risky installs, but removal/install overrides stay approval-gated |
| 17 | |
| 18 | This means `clawsec-suite` can: |
| 19 | - monitor the ClawSec advisory feed, |
| 20 | - track which advisories are new since last check, |
| 21 | - cross-reference advisories against locally installed skills, |
| 22 | - recommend removal for malicious-skill advisories and require explicit user approval first, |
| 23 | - and still act as the setup/management entrypoint for other ClawSec protections. |
| 24 | |
| 25 | ## Included vs Optional Protections |
| 26 | |
| 27 | ### Built into clawsec-suite |
| 28 | - Embedded signed advisory trust set: `advisories/feed.json`, `feed.json.sig`, `checksums.json`, `checksums.json.sig`, and `feed-signing-public.pem` |
| 29 | - Portable heartbeat workflow in `HEARTBEAT.md` |
| 30 | - Advisory polling + state tracking + affected-skill checks |
| 31 | - OpenClaw advisory guardian hook package: `hooks/clawsec-advisory-guardian/` |
| 32 | - Setup scripts for hook and optional cron scheduling: `scripts/` |
| 33 | - Guarded installer: `scripts/guarded_skill_install.mjs` |
| 34 | - Dynamic catalog discovery for installable skills: `scripts/discover_skill_catalog.mjs` |
| 35 | |
| 36 | ### Installed separately (dynamic catalog) |
| 37 | `clawsec-suite` does not hard-code add-on skill names in this document. |
| 38 | |
| 39 | Discover the current catalog from the authoritative index (`https://clawsec.prompt.security/skills/index.json`) at runtime: |
| 40 | |
| 41 | ```bash |
| 42 | SUITE_DIR="${INSTALL_ROOT:-$HOME/.openclaw/skills}/clawsec-suite" |
| 43 | node "$SUITE_DIR/scripts/discover_skill_catalog.mjs" |
| 44 | ``` |
| 45 | |
| 46 | Fallback behavior: |
| 47 | - If the remote catalog index is reachable and valid, the suite uses it. |
| 48 | - If the remote index is unavailable or malformed, the script falls back to suite-local catalog metadata in `skill.json`. |
| 49 | |
| 50 | ## Installation |
| 51 | |
| 52 | ### Cross-shell path note |
| 53 | |
| 54 | - In `bash`/`zsh`, keep path variables expandable (for example, `INSTALL_ROOT="$HOME/.openclaw/skills"`). |
| 55 | - Do not single-quote home-variable paths (avoid `'$HOME/.openclaw/skills'`). |
| 56 | - In PowerShell, set an explicit path: |
| 57 | - `$env:INSTALL_ROOT = Join-Path $HOME ".openclaw\\skills"` |
| 58 | - If a path is passed with unresolved tokens (like `\$HOME/...`), suite scripts now fail fast with a clear error. |
| 59 | |
| 60 | ### Option A: Via clawhub (recommended) |
| 61 | |
| 62 | ```bash |
| 63 | npx clawhub@latest install clawsec-suite |
| 64 | ``` |
| 65 | |
| 66 | ### Option B: Manual download with signature + checksum verification |
| 67 | |
| 68 | ```bash |
| 69 | set -euo pipefail |
| 70 | |
| 71 | VERSION="${SKILL_VERSION:?Set SKILL_VERSION (e.g. 0.0.8)}" |
| 72 | INSTALL_ROOT="${INSTALL_ROOT:-$HOME/.openclaw/skills}" |
| 73 | DEST="$INSTALL_ROOT/clawsec-suite" |
| 74 | BASE="https://github.com/prompt-security/clawsec/releases/download/clawsec-suite-v${VERSION}" |
| 75 | |
| 76 | TEMP_DIR="$(mktemp -d)" |
| 77 | trap 'rm -rf "$TEMP_DIR"' EXIT |
| 78 | |
| 79 | # Pinned release-signing public key (verify fingerprint out-of-band on first use) |
| 80 | # Fingerprint (SHA-256 of SPKI DER): 711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8 |
| 81 | RELEASE_PUBKEY_SHA256="711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8" |
| 82 | cat > "$TEMP_DIR/release-signing-public.pem" <<'PEM' |
| 83 | -----BEGIN PUBLIC KEY----- |
| 84 | MCowBQYDK2VwAyEAS7nijfMcUoOBCj4yOXJX+GYGv2pFl2Yaha1P4v5Cm6A= |
| 85 | -----END PUBLIC KEY----- |
| 86 | PEM |
| 87 | |
| 88 | ACTUAL_KEY_SHA256="$(openssl pkey -pubin -in "$TEMP_DIR/release-signing-public.pem" -outform DER | shasum -a 256 | awk '{print $1}')" |
| 89 | if [ "$ACTUAL_KEY_SHA256" != "$RELEASE_PUBKEY_SHA256" ]; then |
| 90 | echo "ERROR: Release public key fingerprint mismatch" >&2 |
| 91 | exit 1 |
| 92 | fi |
| 93 | |
| 94 | ZIP_NAME="clawsec-suite-v${VERSION}.zip" |
| 95 | |
| 96 | # 1) Download release archive + signed checksums manifest + signing public key |
| 97 | curl -fsSL "$BASE/$ZIP_NAME" -o "$TEMP_DIR/$ZIP_NAME" |
| 98 | curl -fsSL "$BASE/checksums.json" -o "$TEMP_DIR/checksums.json" |
| 99 | curl -fsSL "$BASE/checksums.sig" -o "$TEMP_DIR/checksums.sig" |
| 100 | |
| 101 | # 2) Verify checksums manifest signature before trusting any hashes |
| 102 | openssl base64 -d -A -in "$TEMP_DIR/checksums.sig" -out "$TEMP_DIR/checksums.sig.bin" |
| 103 | if ! openssl pkeyutl -verify \ |
| 104 | -pubin \ |
| 105 | -inkey "$TEMP_DIR/release-signing-public.pem" \ |
| 106 | -sigfile "$TEMP_DIR/checksums.sig.bin" \ |
| 107 | -rawin \ |
| 108 | -in "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then |
| 109 | echo "E |