介绍
# ClawSec Suite
这意味着 `clawsec-suite` 可以: - 监控 ClawSec 安全公告源, - 追踪自上次检查以来的新公告, - 将公告与本地安装的技能进行交叉比对, - 针对恶意技能的公告建议移除,并首先要求明确的用户批准, - 并且仍然作为其他 ClawSec 保护机制的设置/管理入口。
## 内置保护与可选保护
### clawsec-suite 内置 - 嵌入式源种子文件:`advisories/feed.json` - `HEARTBEAT.md` 中的便携式心跳工作流 - 公告轮询 + 状态追踪 + 受影响技能检查 - OpenClaw 公告守护钩子包:`hooks/clawsec-advisory-guardian/` - 钩子和可选 cron 调度的设置脚本:`scripts/` - 守护式安装程序:`scripts/guarded_skill_install.mjs` - 可安装技能的动态目录发现:`scripts/discover_skill_catalog.mjs`
### 单独安装(动态目录) `clawsec-suite` 不在此文档中硬编码附加技能的名称。
在运行时从权威索引(`https://clawsec.prompt.security/skills/index.json`)发现当前目录:
```bash SUITE_DIR="${INSTALL_ROOT:-$HOME/.openclaw/skills}/clawsec-suite" node "$SUITE_DIR/scripts/discover_skill_catalog.mjs" ```
回退行为: - 如果远程目录索引可访问且有效,套件将使用它。 - 如果远程索引不可用或格式错误,脚本将回退到 `skill.json` 中的套件本地目录元数据。
## 安装
### 选项 A:通过 clawhub(推荐)
```bash npx clawhub@latest install clawsec-suite ```
### 选项 B:手动下载并进行签名 + 校验和验证
```bash set -euo pipefail
VERSION="${SKILL_VERSION:?Set SKILL_VERSION (e.g. 0.0.8)}" INSTALL_ROOT="${INSTALL_ROOT:-$HOME/.openclaw/skills}" DEST="$INSTALL_ROOT/clawsec-suite" BASE="https://github.com/prompt-security/clawsec/releases/download/clawsec-suite-v${VERSION}"
TEMP_DIR="$(mktemp -d)" trap 'rm -rf "$TEMP_DIR"' EXIT
# Pinned release-signing public key (verify fingerprint out-of-band on first use) # Fingerprint (SHA-256 of SPKI DER): 711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8 RELEASE_PUBKEY_SHA256="711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8" cat > "$TEMP_DIR/release-signing-public.pem" <<'PEM' -----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAS7nijfMcUoOBCj4yOXJX+GYGv2pFl2Yaha1P4v5Cm6A= -----END PUBLIC KEY----- PEM
ACTUAL_KEY_SHA256="$(openssl pkey -pubin -in "$TEMP_DIR/release-signing-public.pem" -outform DER | shasum -a 256 | awk '{print $1}')" if [ "$ACTUAL_KEY_SHA256" != "$RELEASE_PUBKEY_SHA256" ]; then echo "ERROR: Release public key fingerprint mismatch" >&2 exit 1 fi
ZIP_NAME="clawsec-suite-v${VERSION}.zip"
# 1) Download release archive + signed checksums manifest + signing public key curl -fsSL "$BASE/$ZIP_NAME" -o "$TEMP_DIR/$ZIP_NAME" curl -fsSL "$BASE/checksums.json" -o "$TEMP_DIR/checksums.json" curl -fsSL "$BASE/checksums.sig" -o "$TEMP_DIR/checksums.sig"
# 2) Verify checksums manifest signature before trusting any hashes openssl base64 -d -A -in "$TEMP_DIR/checksums.sig" -out "$TEMP_DIR/checksums.sig.bin" if ! openssl pkeyutl -verify \ -pubin \ -inkey "$TEMP_DIR/release-signing-public.pem" \ -sigfile "$TEMP_DIR/checksums.sig.bin" \ -rawin \ -in "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then echo "ERROR: checksums.json signature verification failed" >&2 exit 1 fi
EXPECTED_ZIP_SHA="$(jq -r '.archive.sha256 // empty' "$TEMP_DIR/checksums.json")" if [ -z "$EXPECTED_ZIP_SHA" ]; then echo "ERROR: checksums.json missing archive.sha256" >&2 exit 1 fi
if command -v shasum >/dev/null 2>&1; then ACTUAL_ZIP_SHA="$(shasum -a 256 "$TEMP_DIR/$ZIP_NAME" | awk '{print $1}')" else ACTUAL_ZIP_SHA="$(sha256sum "$TEMP_DIR/$ZIP_NAME" | awk '{print $1}')" fi
if [ "$EXPECTED_ZIP_SHA" != "$ACTUAL_ZIP_SHA" ]; then echo "ERROR: Archive checksum mismatch for $ZIP_NAME" >&2 exit 1 fi
echo "Checksums manifest signature and archive hash verified."
# 3) Install verified archive mkdir -p "$INSTALL_ROOT" rm -rf "$DEST" unzip -q "$TEMP_DIR/$ZIP_NAME" -d "$INSTALL_ROOT"
chmod 600 "$DEST/skill.json" find "$DEST" -type f ! -name "skill.json" -exec chmod 644 {} \;
echo "Installed clawsec-suite v${VERSION} to: $DEST" echo "Next step (OpenClaw): node \"\$DEST/scripts/setup_advisory_hook.mjs\"" ```
## OpenClaw 自动化(钩子 + 可选 Cron)
安装套件后,启用公告守护钩子:
```bash SUITE_DIR="${INSTALL_ROOT:-$HOME/.openclaw/skills}/clawsec-suite" node "$SUITE_DIR/scripts/setup_advisory_hook.mjs" ```
可选:创建/更新一个定期的 cron 提醒(默认每 `6h`),触发主会话公告扫描:
```bash SUITE_DIR="${INSTALL_ROOT:-$HOME/.openclaw/skills}/clawsec-suite" node "$SUITE_DIR/scripts/setup_advisory_cron.mjs" ```
这将添加: - 在 `agent:bootstrap` 和 `/new` (`command:new`) 时扫描, - 将公告 `affected` 条目与已安装的技能进行比较, - 当出现新匹配时通知, - 并在执行任何移除流程之前要求明确的用户批准。
启用钩子后重启 OpenClaw 网关。然后运行一次 `/new` 以强制在下一个会话上下文中进行立即扫描。
## 守护式技能安装流程(双重确认)
当用户要求安装技能时,将其视为第一次请求并运行守护式安装检查:
```bash SUITE_DIR="${INSTALL_ROOT:-$HOME/.openclaw/skills}/clawsec-suite" node "$SUITE_DIR/scripts/guarded_skill_install.mjs" --skill helper-plus --version 1.0.1 ```
行为: - 如果未发现公告匹配,则继续安装。 - 如果省略 `--version`,匹配将是保守的:任何引用该技能名称的公告都将被视为匹配。 - 如果发现公告匹配,脚本将打印公告上下文并以代码 `42` 退出。 - 然后要求用户进行明确的第二次确认,并使用 `--confirm-advisory` 重新运行:
```bash node "$SUITE_DIR/scripts/guarded_skill_install.mjs" --skill helper-plus --version 1.0.1 --confirm-advisory ```
这强制执行: 1. 第一次确认:用户要求安装。 2. 第二次确认:用户在查看公告详情后明确批准安装。
## 嵌入式公告源行为
嵌入式源逻辑使用以下默认值:
- 远程源 URL:`https://clawsec.prompt.security/advisories/feed.json` - 远程源签名 URL:`${CLAWSEC_FEED_URL}.sig`(可通过 `CLAWSEC_FEED_SIG_URL` 覆盖) - 远程校验和清单 URL:同级 `checksums.json`(可通过 `CLAWSEC_FEED_CHECKSUMS_URL` 覆盖) - 本地种子回退:`~/.openclaw/skills/clawsec-suite/advisories/feed.json` - 本地源签名:`${CLAWSEC_LOCAL_FEED}.sig`(可通过 `CLAWSEC_LOCAL_FEED_SIG` 覆盖) - 本地校验和清单:`~/.openclaw/skills/clawsec-suite/advisories/checksums.json` - 固定的源签名公钥:`~/.openclaw/skills/clawsec-suite/advisories/feed-signing-public.pem`(可通过 `CLAWSEC_FEED_PUBLIC_KEY` 覆盖) - 状态文件:`~/.openclaw/clawsec-suite-feed-state.json` - 钩子速率限制环境变量(OpenClaw 钩子):`CLAWSEC_HOOK_INTERVAL_SECONDS`(默认 `300`)
**故障关闭验证:** 默认情况下需要源签名。当伴随的校验和工件可用时,将验证校验和清单。仅当采用此版本但上游尚未提供签名源工件时,将 `CLAWSEC_ALLOW_UNSIGNED_FEED=1` 作为临时的迁移旁路。
### 快速源检查
```bash FEED_URL="${CLAWSEC_FEED_URL:-https://clawsec.prompt.security/advisories/feed.json}" STATE_FILE="${CLAWSEC_SUITE_STATE_FILE:-$HOME/.openclaw/clawsec-suite-feed-state.json}"
TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT
if ! curl -fsSLo "$TMP/feed.json" "$FEED_URL"; then echo "ERROR: Failed to fetch advisory feed" exit 1 fi
if ! jq -e '.version and (.advisories | type == "array")' "$TMP/feed.json" >/dev/null; then echo "ERROR: Invalid advisory feed format" exit 1 fi
mkdir -p "$(dirname "$STATE_FILE")" if [ ! -f "$STATE_FILE" ]; then echo '{"schema_version":"1.0","known_advisories":[],"last_feed_check":null,"last_feed_updated":null}' > "$STATE_FILE" chmod 600 "$STATE_FILE" fi
NEW_IDS_FILE="$TMP/new_ids.txt" jq -r --argfile state "$STATE_FILE" '($state.known_advisories // []) as $known | [.advisories[]?.id | select(. != null and ($known | index(.) | not))] | .[]?' "$TMP/feed.json" > "$NEW_IDS_FILE"
if [ -s "$NEW_IDS_FILE" ]; then echo "New advisories detected:" while IFS= read -r id; do [ -z "$id" ] && continue jq -r --arg id "$id" '.advisories[] | select(.id == $id) | "- [\(.severity | ascii_upcase)] \(.id): \(.title)"' "$TMP/feed.json" done < "$NEW_IDS_FILE" else echo "FEED_OK - no new advisories" fi ```
## 心跳集成
使用套件心跳脚本作为单一周期性安全检查入口:
- `skills/clawsec-suite/HEARTBEAT.md`
它处理: - 套件更新检查, - 源轮询, - 新公告检测, - 受影响技能交叉比对, - 针对恶意/移除公告的批准门控响应指导, - 以及持久状态更新。
## 批准门控响应合约
如果公告指示恶意或建议移除的技能,且该技能已安装:
1. 立即通知用户公告详情和严重性。 2. 建议移除或禁用受影响的技能。 3. 仅将原始安装请求视为第一次意图。 4. 在执行删除/禁用操作之前(或继续进行有风险的安装之前)要求明确的第二次确认。 5. 仅在第二次确认后才继续。
套件钩子和心跳指导默认情况下是有意非破坏性的。
## 公告抑制 / 允许列表
公告守护管道支持针对已由安全团队审查并接受的公告进行可选抑制。这对于自有工具或不适用于您部署的公告非常有用。
### 激活
公告抑制只需要一个门槛:配置文件必须在数组中包含带有 `"advisory"` 的 `"enabledFor"`。不需要 CLI 标志 —— 配置文件中的标记本身就是选择加入的门槛。
如果 `enabledFor` 数组缺失、为空或不包含 `"advisory"`,则所有公告将正常报告。
### 配置文件解析(4 层)
公告守护使用与审计管道相同的优先级顺序解析抑制配置:
1. 显式 `--config <path>` 参数 2. `OPENCLAW_AUDIT_CONFIG` 环境变量 3. `~/.openclaw/security-audit.json` 4. `.clawsec/allowlist.json`
### 配置格式
```json { "enabledFor": ["advisory"], "suppressions": [ { "checkId": "CVE-2026-25593", "skill": "clawsec-suite", "reason": "First-party security tooling — reviewed by security team", "suppressedAt": "2026-02-15" }, { "checkId": "CLAW-2026-0001", "skill": "example-skill", "reason": "Advisory does not apply to our deployment configuration", "suppressedAt": "2026-02-16" } ] } ```
### 标记语义
- `"enabledFor": ["advisory"]` -- 仅激活公告抑制 - `"enabledFor": ["audit"]` -- 仅激活审计抑制(对公告管道无影响) - `"enabledFor": ["audit", "advisory"]` -- 两个管道都遵守抑制 - 缺失或空的 `enabledFor` -- 无抑制激活(安全默认值)
### 匹配规则
- **checkId:** 与公告 ID 的精确匹配(例如 `CVE-2026-25593` 或 `CLAW-2026-0001`) - **skill:** 与公告中受影响技能名称的不区分大小写的匹配 - 两个字段都必须匹配才能抑制公告
### 每个抑制条目的必填字段
| 字段 | 描述 | 示例 | |-------|-------------|---------| | `checkId` | 要抑制的公告 ID | `CVE-2026-25593` | | `skill` | 受影响的技能名称 | `clawsec-suite` | | `reason` | 审计跟踪的正当理由(必填) | `自有工具,已由安全团队审查` | | `suppressedAt` | ISO 8601 日期 (YYYY-MM-DD) | `2026-02-15` |
### 与审计管道共享配置
公告和审计管道共享同一个配置文件。使用 `enabledFor` 数组来控制哪些管道遵守抑制列表:
```json { "enabledFor": ["audit", "advisory"], "suppressions": [ { "checkId": "skills.code_safety", "skill": "clawsec-suite", "reason": "First-party tooling — audit finding accepted", "suppressedAt": "2026-02-15" }, { "checkId": "CVE-2026-25593", "skill": "clawsec-suite", "reason": "First-party tooling — advisory reviewed", "suppressedAt": "2026-02-15" } ] } ```
审计条目(带有如 `skills.code_safety` 的检查标识符)仅由审计管道匹配。公告条目(带有如 `CVE-2026-25593` 或 `CLAW-2026-0001` 的公告 ID)仅由公告管道匹配。每个管道过滤其自己的相关条目。
## 可选技能安装
动态发现当前可用的可安装技能,然后安装您想要的技能:
```bash SUITE_DIR="${INSTALL_ROOT:-$HOME/.openclaw/skills}/clawsec-suite" node "$SUITE_DIR/scripts/discover_skill_catalog.mjs"
# then install any discovered skill by name npx clawhub@latest install <skill-name> ```
还提供机器可读的输出用于自动化:
```bash node "$SUITE_DIR/scripts/discover_skill_catalog.mjs" --json ```
## 安全说明
- 在信任 `checksums.json` 的文件 URL/哈希之前,始终验证其签名,然后验证每个文件的校验和。 - 验证公告源的分离签名;不要在临时迁移窗口之外启用 `CLAWSEC_ALLOW_UNSIGNED_FEED`。 - 保持公告轮询速率受限(两次检查之间至少 5 分钟)。 - 将影响已安装技能的 `critical`(严重)和 `high`(高危)公告视为立即处理事项。 - 如果您从独立的 `clawsec-feed` 迁移出去,请保留一个规范的状态文件以避免重复通知。 - 在首次使用之前,通过带外方式固定并验证公钥指纹。