omp packages

pi-vetter0.4.2

Security vetting for Pi extension packages — evidence-driven evaluation before install/update

GitHub Actions Published 16 days ago MIT ~638 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-vetter

English

npm version npm downloads license node

Pi 扩展包的安全评估器——在安装或更新之前做证据驱动的门禁。

Pi 以完整用户权限安装扩展包并执行其 postinstall 脚本,而内建更新提示只告诉你"有更新"。pi-vetter 对每个候选版本做多路证据评估,给出 ALLOW / ASK / DENY 判定与完整证据清单,由你决定装什么——然后只安装你批准的版本,更新策略始终掌握在你手里。

pi-vetter 只能证明"未发现风险信号",永远无法证明一个包是安全的。请阅读证据,而不只看判定。

pi-vetter 在 Pi TUI 中运行 /vet——单包判定、风险分与完整证据清单

安装

pi install npm:pi-vetter

(需要 Node ≥ 22.19.0;无需任何 API key——默认扫描器全部免费)

用法

命令 作用
/vet 只读评估。不带参数 = 检查全部已装扩展的可用更新;也可指定:/vet npm:foo npm:bar@1.2.3
/vet-install 同样评估,然后交互多选(TUI 复选框;非 TUI 模式退化为分组确认),只安装你批准的包

批准的包通过 pi install npm:<pkg>@<version> 安装——装的就是评估过的那个版本,且每次安装前重新比对 registry 完整性(TOCTOU 防护)。安装前会对比安装 registry(npm config get registry,即 pi/npm 实际解析所经)与审查 registry(PI_VETTER_NPM_REGISTRY);二者不一致时跳过安装并给出指引,而非在无法验证的链路上继续。安装成功后还会将落盘的包文件与扫描 tarball 的逐文件摘要比对:一致则标注 verified,出现差异则给出带移除命令的警告(属检测而非预防——lifecycle 脚本此刻已经执行)。默认在安装成功后把 settings 条目还原为非 pin spec(ADR-0003 修订版):"让这个包从此退出更新通道"是你的决定而非评估器的副作用——安装结果会给出精确的 pin 命令供你自行执行(install.pinOnInstall: true 恢复旧的总是 pin 行为)。pinned 包在每次 /vet 中照常评估并在报告中标注。

判定模型

  • ALLOW —— 已启用的扫描器未发现风险信号
  • ASK —— 某条规则触发(如新增 lifecycle 脚本、新增外联端点、维护者变更),或证据不完整
  • DENY —— 明确的恶意/矛盾证据(OpenSSF 恶意包通告、provenance 矛盾、VirusTotal 检出)

fail-closed:任一已启用的扫描器失败或超时,判定封顶为 ASK——绝不静默 ALLOW(ADR-0002)。已成立的 DENY 永不被降级。判定由规则驱动;0–100 的风险分仅作展示(ADR-0001)。每份报告还会展示已验证 tarball 的 sha256,锚定其评估的确切 artifact。

扫描器(Phase 1)

层 扫描器 来源
L0 metadata npm registry packument:维护者(本地快照比对)、包龄、发布节奏、废弃标记、下载量
L1 osv osv.dev querybatch —— 覆盖 CVE + GitHub Advisory (GHSA) + OpenSSF 恶意包 (MAL-);新增依赖也一并查询,且按 npm 实际会解析的版本(range 内最新已发布版本)查询
L1 provenance npm attestations:对 vendored 公共 TrustedRoot 做完整 sigstore 签名链验证 + 声明仓库矛盾检测;验证通过产出 provenance:verified。缺失 attestations 默认为 info,开启 provenance.required 后升为 ASK
L2 static 代码文件模式扫描:凭据访问、混淆特征、prompt-injection 标记、eval 族与动态模块解析(拼接 / base64 解码 / 变量 require-import);既有命中为 info,新命中为 finding;install 场景(无基线)凭据/混淆命中降为 info,prompt-injection 与动态代码执行始终为硬信号
L2 diff 新旧 tarball 对比:新增 lifecycle 脚本、新增依赖、新增 child_process、新增外联端点
L3 virustotal 先按哈希查询已有样本、未命中再上传(上传新文件不消耗每日配额);≥2 引擎检出 → DENY。默认关闭,配置 API key 启用
L3 socket Socket.dev 包告警(gptMalware、installScripts、obfuscatedFile、typosquatting 等);高风险告警 → ASK(socket-flagged)。默认关闭——注意免费 token 的配额是按调用扣减的余额制(每次 purl 查询消耗一块),余额耗尽后常态性配额不足(判定将封顶 ASK)

可选 L3 引擎默认关闭,在配置文件中按 API key 逐个启用。当已启用引擎配额耗尽或失败时,判定封顶为 ASK(fail-closed),证据中说明原因。

规则

规则把证据映射到判定,可在配置文件中逐条开关(如 ask.new-lifecycle-script: false)。当前 DENY 规则:malicious-package、provenance-conflict、vt-detections。当前 ASK 规则:known-vulnerability、new-lifecycle-script、maintainer-change、new-dependency-flagged、new-network-endpoint、new-child-process、credential-access、dynamic-code-execution、transitive-risk、obfuscation、prompt-injection-marker、young-package、rapid-release、deprecated-candidate、provenance-missing(仅当 provenance.required 开启)。被禁用的规则会在报告 Notes 中披露,ALLOW 不会伪装成完整扫描。

配置

~/.pi/agent/pi-vetter/config.json(首次运行自动生成默认值;样例见 config.example.json)。若 scanner 设了 enabled: true 但缺少凭据,该 scanner 不会注册——命令开始时会给出 warning 通知,报告 Notes 中也会逐条披露被跳过的 scanner(两家 API 均无匿名访问;VirusTotal 与 Socket 的免费额度都需要注册换取 key):

{
  "scanners": { "osv": { "enabled": true, "timeoutMs": 10000 }, "virustotal": { "enabled": false, "apiKey": "" } },
  "rules": { "deny": {}, "ask": { "young-package": true } },
  "provenance": { "required": false },
  "cache": { "enabled": true, "ttlHours": 24 },
  "score": { "weights": {} },
  "network": { "timeoutMs": 30000 },
  "install": { "pinOnInstall": false }
}

扫描结果按 扫描器 + 包@版本 + 基线版本 + artifact 摘要(candidate 与 baseline 两侧)缓存在 ~/.pi/agent/pi-vetter/cache/;VirusTotal 哈希查询永久缓存。缓存可整体关闭。

环境变量

可选的端点覆盖(未设置时使用公共默认值),适用于私有 registry/镜像:

变量 默认值 用途
PI_VETTER_NPM_REGISTRY https://registry.npmjs.org npm registry 基础 URL
PI_VETTER_DOWNLOADS_API https://api.npmjs.org/downloads/point/last-month 下载量 API 基础 URL
PI_VETTER_OSV_API https://api.osv.dev OSV API 基础 URL
PI_VETTER_DATA_DIR ~/.pi/agent/pi-vetter 数据目录(配置、缓存、维护者快照)
PI_VETTER_AGENT_DIR ~/.pi/agent agent 目录(读取 settings.json 获取已安装清单)

注意事项

  • 批准安装仍会执行该包的 install 脚本——Pi 安装不带 --ignore-scripts;pi-vetter 会警告但无法阻止
  • 依赖深扫(dependencies.* 配置,默认开启、深度 2 / 上限 20 个包)会下载并静态扫描传递依赖 tarball——每个依赖解析为声明 range 内的最高已发布版本(range 无普通 semver 形状或无匹配版本时回退 latest,因此扫描的 tarball 偶尔会与 npm 实际安装的版本不同);命中逐依赖归属标注:风险类(凭据、混淆、prompt injection、动态代码)升为 ASK 级 transitive-risk 规则,普通 Node.js API 用法保持 info。
  • 自举供应链:pi-vetter 自身的运行时依赖(@sigstore/bundle、@sigstore/verify、tar-stream)同样是 npm 包,与它所评估的一切存在同样的理论投毒风险——评估器无法把自己举到自身供应链之上。请像审计任何拥有完整权限的工具一样审计它的 lockfile
  • 非 npm 源(git/本地路径)不在 MVP 范围内——无参数的 /vet 不会评估它们,但会在报告 Notes 中逐条披露被跳过的源

开发

npm install
npm run typecheck && npm test && npm run lint
npx vitest run --project e2e                                # 端到端测试(本地 fake registry)
LIVE_E2E=1 npx vitest run --project live                    # 真实 registry 端到端评估(联网)

设计文档:docs/design.md(中文)、ADR 见 docs/adr/、调研报告见 research/。

许可证

MIT