SkillLite开源项目安全策略清单梳理
本文目的:把 SkillLite 当前已经存在的安全策略以可核对的方式完整盘点一次(每条都给到模块路径与关键类型),并诚实标注哪些是分散重复的、哪些是覆盖不全的。
适用范围:仓库内工程视角。不是用户运行时配置手册(运行时配置见
docs/{en,zh}/ENV_REFERENCE.md)。编写约束:所有结论均来自代码与
spec/实际内容;无引用即无结论。
0. 威胁模型与设计目标
SkillLite 的威胁模型至少包含以下场景:
- 任意 LLM 生成的脚本(agent loop 自写自跑);
- 第三方 ClawHub / vercel-labs / 个人 GitHub 拉取的 Skill;
- 演化(Evolution)流程自动产出的新 Skill;
- OpenClaw / Hermes 风格目录 一次性导入的批量 Skill;
- bash-tool 类 Skill 由 LLM 即时拼出 shell 命令。
设计目标(见 spec/security-nonnegotiables.md):
- 默认关闭危险操作的自动放行;
- 默认收紧网络/文件/进程;
- 高风险路径走两阶段确认(先扫描,再执行);
- Linux 后端fail-closed(无可用隔离后端时拒绝执行,除非显式打开受控降级)。
1. 三段式分层:执行前 / 执行中 / 治理与可观测
1.1 端到端决策流程(pre-execution → runtime → 结果)
1.2 静态分层一览(按模块归类)
┌────────────────────────────────────────────────────────────┐
│ Pre-execution (静态防线) │
│ · SKILL.md 可疑模式扫描 (skill_md_security) │
│ · 入口脚本静态扫描 (security/scanner) │
│ · 依赖供应链审计 OSV/PyPI (security/dependency_audit) │
│ · 已知恶意/抢注包名库 (security/malicious_packages) │
│ · bash 命令验证器 (bash_validator) │
│ · 元数据 / 锁 / 信任评分 (skill::metadata / trust) │
└────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────┐
│ Runtime (隔离防线) │
│ · L1/L2/L3 沙箱级别 (sandbox::runner) │
│ · macOS Seatbelt (sandbox::seatbelt + macos) │
│ · Linux bwrap + seccomp (sandbox::linux + seccomp) │
│ · 强制写入拒绝 / 移动保护 (security::policy) │
│ · 网络代理 (HTTP+SOCKS5) (sandbox::network_proxy) │
│ · Mach / IOKit 拒绝 (security::policy 常量) │
│ · 资源限制 (内存/超时) (sandbox::runner::ResourceLimits)│
└────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────┐
│ Governance & Observability (治理与可观测) │
│ · 技能 Trust Tier + Decision (skill::trust) │
│ · 技能名 Denylist (skill::denylist) │
│ · 演化审计 (sqlite + jsonl) (evolution::audit) │
│ · 输入输出脱敏 (audit_preview_redact) │
│ · 演化风险预算 / 分级授权 (evolution coordinator) │
│ · 治理规范 spec/ (10 份强制注入规则) │
└────────────────────────────────────────────────────────────┘
2. Pre-execution(静态防线)
2.1 SKILL.md 可疑模式扫描
- 文件:
crates/skilllite-core/src/skill/skill_md_security.rs - 入口:
scan_skill_md_suspicious_patterns(content) -> Vec<SkillMdAlert> - 检测项(部分实证):
- High:
| bash/| sh/base64 -d/pastebin.com/rentry.co - Medium:「run in terminal」「在终端中运行」等指令式社工话术
- High:
- 调用点:
skill_precheck::run_skill_precheck(见 §3.0);任何沙箱级别(L1–L3)执行前都会跑一次。
2.2 入口脚本静态扫描(多语言)
- 文件:
crates/skilllite-sandbox/src/security/scanner.rs、security/default_rules.rs、security/rules.rs、security/types.rs - 入口:
ScriptScanner::scan_file(path)/scan_shell_command(cmd) - 覆盖语言:Python / JavaScript(Node) / Shell;规则形态包括 base64 解码、多阶段下载-解码-执行检测、明显的
eval/exec/child_process.spawn等。 - 配置:项目根可放
.skilllite-rules.yaml,支持disabled_rules与自定义规则(见security/mod.rs顶部 docstring)。 - 严重性等级:
Critical / High / Medium / Low / Info,Critical 不可被用户确认覆盖(见SKILL_PRECHECK_CRITICAL_BLOCKED)。
2.3 依赖供应链审计
- 目录:
crates/skilllite-sandbox/src/security/dependency_audit/(6 个子文件) - 入口:
audit_skill_dependencies(skill_dir, ...),feature-gated 在audit之后 - 后端优先级(
mod.rs文档):- 自定义 API:
SKILLLITE_AUDIT_API(覆盖其它) - PyPI JSON API:仅 Python,
PYPI_MIRROR_URL - OSV.dev API:npm / 兜底,
OSV_API_URL
- 自定义 API:
- 解析器:
requirements.txt、package.json(见parsers.rs)。
2.4 已知恶意 / 抢注包名库(离线)
- 文件:
crates/skilllite-sandbox/src/security/malicious_packages.rs - 形态:静态切片 + 二分查找;条目按字典序排序,单元测试校验不变量。
- 用途:在装包前对名字做拦截(PyPI / npm 双侧),不依赖网络。
2.5 bash 命令验证器(bash-tool Skill 专用)
- 文件:
crates/skilllite-sandbox/src/bash_validator.rs - 关键策略(按代码注释):
- 链式操作符全部禁:
;、&&、||、|、反引号、$(...)、${...}、换行、>( - 必须匹配 SKILL.md
allowed-tools: Bash(prefix:*)的前缀 - 始终拒绝:
rm、sudo、su、sh、curl、… - Unicode NFKC 归一化后再校验,防同形字符绕过(
rmvsrm)
- 链式操作符全部禁:
- 在 Rust 编译路径里执行,Python SDK 层无法绕过(注释明示)。
2.5.1 依赖解析优先级(detect_dependencies)
2.6 元数据 / 锁 / 信任评分(pre-spawn)
- 文件:
crates/skilllite-core/src/skill/{metadata.rs, dependency_resolver.rs, deps.rs, manifest.rs, trust.rs, openclaw_metadata.rs} .skilllite.lock:compatibility_hash与解析包列表绑定,stale → 重新解析(dependency_resolver::resolve_from_lock)。- 内置 Python / Node 包白名单:
dependency_resolver::PYTHON_PACKAGES/NODE_PACKAGES(数百条),--allow-unknown-packages才能绕过。 - 信任评分(
skill::trust::assess_skill_trust):- 输入:
source、SignatureSignal、IntegritySignal、扫描结果 - 输出
TrustTier:Trusted (≥85) / Reviewed (≥65) / Community (≥40) / Unknown - 输出
TrustDecision:Allow / RequireConfirm / Deny - 已知信任源(评分加分):
clawhub:、github.com/exboys/skilllite
- 输入:
2.6.1 Trust 决策树(assess_skill_trust)
2.7 OpenClaw / ClawHub metadata 兼容(2026-04-19 新增)
- 文件:
crates/skilllite-core/src/skill/openclaw_metadata.rs - 别名识别:
metadata.openclaw/clawdbot/clawdis(首个带「合并信号」的优先,openclaw优先于后续别名) - 折入
compatibility文本:requires.{bins,anyBins,env,config}、primaryEnv、os、skillKey、always、install[]摘要 - 结构化暴露:
SkillMetadata.openclaw_installs: Option<OpenClawInstalls> - 依赖路由(
skill::deps::detect_dependencies):kind: node→DependencyType::Node(npm 安装)kind: uv→DependencyType::Python(pip 安装)kind: brew | go | <unknown>→ 不自动安装,仅记录(info/warn)
3. Runtime(隔离防线)
3.0 双阶段:precheck → spawn
- 文件:
crates/skilllite-sandbox/src/security/skill_precheck.rs+runner.rs - 流程:
run_skill_precheck → SkillPrecheckSummary { review_text, has_critical_script_issue },再决定是否进入沙箱。 - 任意 sandbox level 都跑 precheck(注释:
Pre-spawn static precheck for skills (all sandbox levels))。 - Critical 命中时不允许用户覆盖;其它级别可在 UI/MCP 层提示。
3.1 沙箱级别 L1 / L2 / L3
- 类型:
crates/skilllite-sandbox/src/runner.rs::SandboxLevel - 语义:
Level1— 不进沙箱,直接执行(只在显式选择时使用)Level2— 进沙箱,但不做静态扫描Level3(默认)— 进沙箱 + 静态扫描
- 解析顺序:
CLI > config (SKILLLITE_*) > Level3 默认。
3.2 平台后端
- macOS:
crates/skilllite-sandbox/src/macos.rs(785 行)+seatbelt.rs,把security::policy翻译成 Seatbelt profile。 - Linux:
crates/skilllite-sandbox/src/linux.rs(869 行)使用bubblewrap (bwrap);同时叠加seccomp.rs内核级 syscall 拦截:- 拦截:
socket(AF_UNIX)、ptrace、mount/umount2、clone(CLONE_NEWUSER)、unshare(CLONE_NEWUSER)、keyctl、kexec_*、pivot_root、chroot - 体系结构:x86_64 + aarch64
- 拦截:
- Windows:
crates/skilllite-sandbox/src/windows.rs(占位/受限)。 - Linux 缺有效后端时默认 fail-closed(
spec/security-nonnegotiables.md)。
3.3 强制写入拒绝(所有平台共用)
- 文件:
crates/skilllite-sandbox/src/security/policy.rs(单一来源) - 常量分类(每条都是
&[&str],被 macOS/Linux 翻译器取用):MANDATORY_DENY_SHELL_CONFIGS:.bashrc / .zshrc / .profile / fish/config.fish / …MANDATORY_DENY_GIT_CONFIGS:.gitconfig / .git/hooks/*MANDATORY_DENY_IDE_CONFIGS:.vscode/* / .idea/* / .vimrc / nvim init / …MANDATORY_DENY_PACKAGE_CONFIGS:.npmrc / .yarnrc / .pypirc / .cargo/config / .gemrc / …MANDATORY_DENY_SECURITY_FILES:.ssh/* / .gnupg/* / .aws/* / .kube/* / .docker/* / .netrcMANDATORY_DENY_AGENT_CONFIGS:.mcp.json / .claude/* / .cursor/* / .continue/* / .aider.conf.yml / .copilot/* / .codeium/*MANDATORY_DENY_DIRECTORIES:.ssh / .gnupg / .aws / .kube / .docker / .git/hooks / .vscode / .idea / .claude / .cursor
3.4 移动保护(防 mv/rename 绕过)
- 文件:
crates/skilllite-sandbox/src/move_protection.rs+security::policy::get_move_protection_paths - 典型:
~/.ssh / ~/.aws / ~/.gnupg / ~/.kube / ~/.docker / ~/.git/hooks / ~/.bashrc / ~/.zshrc / **/.git/hooks / **/.env - LogTag 机制(同文件):每进程会话生成
_{rand}_SBX后缀,用于精确追踪违规事件。
3.5 进程执行策略
- 文件:
security::policy - macOS:白名单策略——只放过解析后的 interpreter 路径,其它
process-exec一律 deny(policy.rs第 §“Process Execution Policy”)。 - Linux(firejail/bwrap):使用
PROCESS_DENYLIST_ALWAYS:/bin/{bash,zsh,sh}, /usr/bin/env, /usr/bin/curl, /usr/bin/wget, /usr/bin/ssh, /usr/bin/scp, /bin/rm, /bin/chmod - 严格模式额外拒:
/usr/bin/git(PROCESS_DENYLIST_STRICT_ONLY)。 - macOS-only 拒:
/usr/bin/osascript。
3.6 IPC / Kernel(macOS)
MACH_DENY_ALWAYS:mach-register、mach-priv-task-portIOKIT_DENY_ALWAYS:iokit-open- 这三项在所有 Seatbelt profile 中始终 deny,目的:防 IPC 注入与直接 IOKit 内核驱动访问。
3.7 网络代理(域级过滤)
- 目录:
crates/skilllite-sandbox/src/network_proxy/(HTTP / SOCKS5 / DNS / Tunnel / Manager / Config / Tests) - 形态:在宿主机起 HTTP + SOCKS5 双代理,沙箱内只允许连
localhost:proxy_port。 - 策略解析:
security::policy::resolve_network_policy(network_enabled, outbound) -> ResolvedNetworkPolicyBlockAll— 网络关AllowAll— 仅当 outbound 含纯*(不带端口)时绕过代理ProxyFiltered { domains }— 走代理白名单
- macOS:Seatbelt profile 只放 localhost;Linux:移除 net namespace + Unix socket 转发。
3.7.1 网络策略解析(resolve_network_policy)
3.8 资源限制
crates/skilllite-sandbox/src/runner.rs::ResourceLimits- 默认(
common.rs中常量):max_memory_mb=256、timeout_secs=30 - 可被
SKILLLITE_*config 覆盖、再被 CLI flag 覆盖。
3.9 Relaxed mode(L2 与 Playwright)
is_relaxed_mode()↔sandbox_level == 2should_allow_playwright()=is_relaxed_mode() || is_playwright_allowed()- 项目级敏感读 regex(
get_sensitive_read_project_regex_patterns)在 relaxed 下放宽.git/、.env、.env.*三条。
4. Governance / Observability(治理与可观测)
4.1 技能名 Denylist(手动黑名单)
- 文件:
crates/skilllite-core/src/skill/denylist.rs - 来源(合并):
SKILLLITE_SKILL_DENYLIST(逗号/分号分隔)~/.skilllite/skill-denylist.txt{data_root}/.skilllite/skill-denylist.txt./.skilllite/skill-denylist.txt
- 命中即在沙箱执行前直接拒绝。
4.2 Trust Tier 决策
- 见 §2.6。注意
assess_skill_trust在以下任一信号触发时直接返回 Deny:IntegritySignal::HashChangedIntegritySignal::SignatureInvalidSignatureSignal::Invalidhas_critical_scan == true
4.3 演化审计(Evolution)
- 文件:
crates/skilllite-evolution/src/audit.rs - 双写:
- SQLite
evolution_log(ts, type, target_id, reason, version) - JSONL
evolution.log(每行一个 event)
- SQLite
- 同时通过
skilllite_core::observability::audit_evolution_event旁路写出。
4.4 输入输出脱敏
- 文件:
crates/skilllite-core/src/audit_preview_redact.rs - 命中:
- 关键字键(已规范化):
api_key/apikey/api-key/password/passwd/pwd/secret/secret_key/token/access_token/refresh_token/credential/private_key/access_key/auth/authorization - 正则:
sk-[A-Za-z0-9]{20,}、(?i)Bearer\s+[A-Za-z0-9._-]{20,}
- 关键字键(已规范化):
- 应用位置:写 audit log 预览前、observability summary 输出前。
4.5 演化风险预算与分级授权
- 散落点(未集中到一个 README):
tasks/TASK-2026-013-evolution-policy-runtime-risk-budget、tasks/TASK-2026-016-...rollback-boundary、tasks/TASK-2026-017-partial-failure-evolution-authorization、tasks/TASK-2026-024-auto-confirm-risk-tiers。 - 现状:
coordinator会在低风险预算耗尽时把决策推入队列;策略关闭时拒绝高危执行(见skilllite-evolutionlib_tests::coordinator_*用例族)。
4.6 治理规范(强制注入)
- 目录:
spec/,10 份:verification-integrity.md(最高优先级,所有任务必注入)task-artifact-language.md、architecture-boundaries.md、security-nonnegotiables.mdrust-conventions.md、testing-policy.md、docs-sync.mdstructured-signal-first.md、capability-gap-evolution.mdREADME.md(注入路由)
- 依赖:
scripts/validate_tasks.py校验tasks/TASK-.../形状(STATUS.md必含## Timeline/## Checkpoints,REVIEW.md必含Merge readiness:)。
5. 安全相关配置(环境变量)
完整列表见 docs/{en,zh}/ENV_REFERENCE.md。本文档仅列与本清单直接相关的几个:
| 变量 | 用途 |
|---|---|
SKILLLITE_* 沙箱级别 / relaxed / allow_playwright | SandboxEnvConfig::from_env() 读取 |
SKILLLITE_AUDIT_API | 自定义供应链审计后端 |
PYPI_MIRROR_URL / OSV_API_URL | 审计后端兜底 |
SKILLLITE_SKILL_DENYLIST | 技能名手动黑名单(合并多源) |
SKILLLITE_MEMORY_FLUSH_ENABLED | 演化记忆 pre-compaction(与本文关系较弱,列出仅为完整) |
6. 已知重叠 / 减重机会(诚实标注)
这部分是实情陈述,不是 RFC。未在本文中提议任何代码改动。
-
依赖处理至少分散在三处:
skilllite-core::skill::deps(白名单匹配)skilllite-core::skill::dependency_resolver(Lock → LLM → Whitelist 流水线)skilllite-sandbox::security::dependency_audit(OSV/PyPI 审计)
接口未统一,新增字段需要同时改两处或三处。
-
审计 / 可观测有 ≥3 套:
skilllite-core::audit_preview_redact(脱敏)skilllite-evolution::audit(演化双写)skilllite-commands::audit_report(CLI 报告)
schema、字段、入口都不一样。
-
「policy / rules / default_rules」三件套:
security/policy.rs+security/rules.rs+security/default_rules.rs没有统一 trait,靠文件名分工。 -
代码扫描表面三处入口:
skill_md_security.rs(markdown)+bash_validator.rs(bash)+security/scanner.rs(通用脚本),各自独立。 -
requires.bins/requires.env当前只是声明,没运行时校验:
合并进compatibility文本,技能真跑起来缺 bin/缺 env 仍要靠脚本自身报错。 -
OpenClaw
install[]结构化包绕过白名单 gate:
见tasks/TASK-2026-034-openclaw-metadata-and-install/CONTEXT.md的 Open Questions。 -
Linux 后端拒绝时的体验:
缺bwrap时 fail-closed 是设计意图(spec/security-nonnegotiables.md),但用户提示链路是否清晰需要再核对(本清单未单测)。
7. 不可商量底线(直接引用 spec)
引自 spec/security-nonnegotiables.md:
- Must:保留 L1/L2/L3 默认语义;保留两阶段确认;Linux fail-closed;关键安全事件可审计;策略变更必须配单测/回归。
- Must Not:不默认放行危险操作;不静默放宽网络/文件系统/进程;不删除完整性检查(hash/篡改检测);不擅自改默认 deny 规则。
8. 验证命令(自检)
以下命令任何修改后都应能跑通:
cargo test -p skilllite-sandbox
cargo test -p skilllite-core
cargo test -p skilllite-evolution -p skilllite-agent
cargo audit # cargo 漏洞库
python3 scripts/validate_tasks.py # tasks/ 形状校验
9. 维护说明
- 本文档只描述当前已存在的策略;不要把未实现的提案写进来(与
spec/docs-sync.md的 Quality Bar 一致)。 - 每次新增/合并安全模块,请回头更新本文相应章节并附 commit。
- 如需 EN 版本:复制为
docs/articles/security-strategy-inventory.en.md并保持节标题一致;目前spec/docs-sync.md没有把docs/articles/列入强制双语清单,但若你将本文链入README/ARCHITECTURE,按既定规范应同步 EN。
开源项目地址:https://github.com/EXboys/skilllite
更多推荐



所有评论(0)