supply-chain-check
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSupply-chain hygiene audit
供应链卫生审计
A defense-in-depth audit against npm-ecosystem supply-chain attacks (typosquatting, hijacked maintainer accounts, malicious postinstall scripts). Walks the user through their developer machine + the current project + CI workflows, then offers fixes one-by-one with explicit confirmation.
针对npm生态系统供应链攻击(打字错误包、被劫持的维护者账户、恶意postinstall脚本)进行深度防御审计。引导用户检查其开发机器 + 当前项目 + CI工作流,然后逐一提供修复方案并要求明确确认。
Operating rules (read first)
操作规则(请先阅读)
- Audit before fix. Always run the full audit and present findings before proposing any change.
- Confirm every write. Show the file path and the exact content you will write. Ask y/n. Never batch-apply.
- Never execute remote installers. If Safe Chain is missing, print the install command and link; do not run yourself.
curl ... | sh - Never auto-edit CI workflow files. YAML structure varies (matrices, reusable workflows). Print the snippet and the suggested path; let the user place it.
- Render policy values at runtime. Read from this skill's directory and substitute
policy.jsonetc. into templates before showing them.{{VERSION}} - Surface intentional overrides as warnings, not failures. is a deliberate choice — flag for review, recommend
ignore-scripts=false, do not propose flipping.@lavamoat/allow-scripts
- 先审计后修复。在提出任何更改之前,始终先完成完整审计并呈现结果。
- 每次写入都需确认。显示文件路径以及将要写入的准确内容。询问是否确认(y/n)。绝不能批量应用更改。
- 绝不执行远程安装程序。如果缺少Safe Chain,请打印安装命令和链接;不要自行运行。
curl ... | sh - 绝不自动编辑CI工作流文件。YAML结构各不相同(矩阵、可复用工作流)。打印代码片段和建议路径;由用户自行放置。
- 运行时渲染策略值。从本技能目录读取,并在展示模板前将
policy.json等变量替换为实际值。{{VERSION}} - 将有意覆盖项标记为警告而非失败。是故意选择的配置——标记以供审查,建议使用
ignore-scripts=false,不要提议修改该配置。@lavamoat/allow-scripts
Phase 1 — Detect environment
阶段1 — 检测环境
Run these in parallel:
- — captures G1
which safe-chain - Read (may not exist) — captures G2
~/.safe-chain/config.json - the cwd for lockfiles to identify the package manager
ls - Check for — if absent, exit with "Not a JS project, nothing to audit."
package.json
Lockfile priority (first match wins):
| Lockfile | Manager | Extra check |
|---|---|---|
| bun | — |
| pnpm | Run |
| yarn berry | — |
| yarn classic v1 | Emit warning, skip P2, continue with P1/P3/CI |
| npm | — |
For yarn classic: emit Do not propose P2 fixes.
⚠ yarn classic detected — no native min-release-age support. Recommend upgrading to Yarn Berry v3+ or switching to pnpm.Also check — if it exists, run CI checks. If / / etc. exist, emit one .
.github/workflows/.gitlab-ci.ymlazure-pipelines.yml⚠ non-GitHub CI detected — unchecked, see https://github.com/AikidoSec/safe-chain#cicd-integration并行运行以下操作:
- — 获取G1状态
which safe-chain - 读取(可能不存在)—— 获取G2状态
~/.safe-chain/config.json - 在当前工作目录执行命令查找锁文件,以识别包管理器
ls - 检查是否存在— 如果不存在,输出“非JS项目,无需审计”并退出
package.json
锁文件优先级(匹配到第一个即生效):
| 锁文件 | 包管理器 | 额外检查 |
|---|---|---|
| bun | — |
| pnpm | 运行 |
| yarn berry | — |
仅 | yarn classic v1 | 发出警告,跳过阶段2,继续执行阶段1/3/CI检查 |
| npm | — |
对于yarn classic:输出 不要提议阶段2的修复方案。
⚠ 检测到yarn classic — 无原生最小发布时长支持。建议升级到Yarn Berry v3+或切换到pnpm。同时检查目录 — 如果存在,运行CI检查。如果存在 / / 其他CI配置文件,输出一条。
.github/workflows/.gitlab-ci.ymlazure-pipelines.yml⚠ 检测到非GitHub CI — 未进行检查,请查看https://github.com/AikidoSec/safe-chain#cicd-integrationPhase 2 — Audit checklist
阶段2 — 审计清单
Present findings as a table. Format: .
[✓/✗/⚠] ID — short label — current → expectedGlobal (machine-level):
| ID | Check |
|---|---|
| G1 | |
| G2 | |
Project (repo-level):
| ID | Check |
|---|---|
| P1 | Lockfile present and not gitignored |
| P2 | PM-specific config has policy values (see below) |
| P3 | |
P2 per manager (load thresholds from ):
policy.json- npm: contains
.npmrc,ignore-scripts=true,min-release-age=3engine-strict=true - pnpm v10+: contains
pnpm-workspace.yamland an explicitminimumReleaseAge: 4320key. Do not flag absence ofonlyBuiltDependencies:— scripts are disabled by default in v10+.ignore-scripts - pnpm v9-: treat as npm — expect with
.npmrc,ignore-scripts=truemin-release-age=3 - yarn berry: contains
.yarnrc.ymlandnpmMinimalAgeGate: 3denableScripts: false - bun: contains
bunfig.tomlsection with[install]. Do not flag absence of script-disable — bun disables postinstalls by default.minimumReleaseAge = 259200
ignore-scripts=false.npmrc⚠ intentional override detected — ensure @lavamoat/allow-scripts is configured as the allowlist (https://github.com/LavaMoat/LavaMoat/tree/main/packages/allow-scripts)CI (only if exists):
.github/workflows/| ID | Check |
|---|---|
| C1 | At least one workflow runs a frozen-lockfile install ( |
| C2 | Safe Chain installer URL pins a specific version (matches |
| C3 | The install step does not use bare |
| C4 | |
After the table, print: . If M+K > 0, ask: "Walk through fixes interactively?" — y/n. If no, stop here.
N passing, M failing, K warnings以表格形式呈现检查结果。格式:。
[✓/✗/⚠] ID — 简短标签 — 当前状态 → 预期状态全局(机器级别):
| ID | 检查项 |
|---|---|
| G1 | |
| G2 | |
项目(仓库级别):
| ID | 检查项 |
|---|---|
| P1 | 锁文件存在且未被git忽略 |
| P2 | 包管理器专属配置包含策略值(见下文) |
| P3 | |
各包管理器的P2检查项(从加载阈值):
policy.json- npm: 包含
.npmrc、ignore-scripts=true、min-release-age=3engine-strict=true - pnpm v10+: 包含
pnpm-workspace.yaml和明确的minimumReleaseAge: 4320键。不要标记缺少onlyBuiltDependencies:的情况——v10+版本默认禁用脚本。ignore-scripts - pnpm v9-: 按npm处理——预期包含
.npmrc、ignore-scripts=truemin-release-age=3 - yarn berry: 包含
.yarnrc.yml和npmMinimalAgeGate: 3denableScripts: false - bun: 包含
bunfig.toml部分,且其中有[install]。不要标记缺少脚本禁用配置的情况——bun默认禁用postinstall脚本。minimumReleaseAge = 259200
ignore-scripts=false.npmrc⚠ 检测到有意覆盖配置 — 确保已将@lavamoat/allow-scripts配置为允许列表(https://github.com/LavaMoat/LavaMoat/tree/main/packages/allow-scripts)CI(仅当存在时):
.github/workflows/| ID | 检查项 |
|---|---|
| C1 | 至少有一个工作流执行冻结锁文件的安装命令( |
| C2 | Safe Chain安装器URL固定了特定版本(与 |
| C3 | 安装步骤未使用裸命令 |
| C4 | Safe Chain安装步骤设置了 |
表格展示后,打印:。如果M+K > 0,询问:"是否逐步引导进行交互式修复?" — y/n。如果选择否,在此处停止。
N项通过,M项失败,K项警告Phase 3 — Interactive fix loop
阶段3 — 交互式修复循环
Iterate failing checks in this order (least invasive first). For each: show the exact change, ask y/n, apply on yes, skip on no.
按以下顺序处理失败的检查项(从侵入性最低的开始)。对于每个项:显示确切的更改内容,询问是否确认(y/n),确认则应用,否则跳过。
Order
顺序
-
G2 — Safe Chain global config
- If is missing: show the JSON, confirm, write it.
~/.safe-chain/config.json - If present but : read existing, show diff, ask before overwriting that key only (preserve other keys).
minimumPackageAgeHours < 72
- If
-
P2 — PM config
- Read existing config file if any.
- Compare key-by-key against the policy.
- For each missing/incorrect key: show old value vs new value, ask y/n.
- Use for surgical merges (preserve unrelated keys, comments, ordering). Only use
Editif the file does not exist.Write - For in
ignore-scripts=false: do not propose change. Print the warning text from Phase 2 and move on..npmrc
-
P3 — CONTRIBUTING/README mention
- If exists: offer to append
CONTRIBUTING.mdto it.templates/contributing.snippet.md - Else if exists: offer to append to README, OR create
README.md— ask which.CONTRIBUTING.md - Else: offer to create from the snippet.
CONTRIBUTING.md
- If
-
C1–C4 — GitHub Actions (never edit workflow files automatically)
- For each failing CI check, print the rendered (with
templates/github-actions.snippet.ymlsubstituted from{{VERSION}}).policy.json - State which file the user should edit (e.g. ) and which step it should go before.
.github/workflows/ci.yml - Do not run Edit or Write on workflow files.
- For each failing CI check, print the rendered
-
G1 — Safe Chain not installed
- Print: followed by the official install command and the link
Safe Chain is not on PATH. Install with:.https://github.com/AikidoSec/safe-chain#installation - Do not execute.
- Print:
After applying each fix, re-run that single check silently and confirm it now passes. If it still fails, surface why and stop the loop.
-
G2 — Safe Chain全局配置
- 如果不存在:展示JSON内容,确认后写入。
~/.safe-chain/config.json - 如果存在但:读取现有内容,显示差异,仅在确认后覆盖该键(保留其他键)。
minimumPackageAgeHours < 72
- 如果
-
P2 — 包管理器配置
- 读取现有配置文件(如果存在)。
- 逐键与策略进行比较。
- 对于每个缺失/错误的键:显示旧值与新值,询问是否确认。
- 使用“编辑”进行精准合并(保留无关键、注释、排序)。仅当文件不存在时使用“写入”。
- 对于中的
.npmrc:不要提议更改。打印阶段2中的警告文本并继续。ignore-scripts=false
-
P3 — CONTRIBUTING/README中的提及
- 如果存在:提议将
CONTRIBUTING.md追加到该文件中。templates/contributing.snippet.md - 如果不存在但存在:提议追加到README,或创建
README.md——询问选择哪种方式。CONTRIBUTING.md - 如果两者都不存在:提议从代码片段创建。
CONTRIBUTING.md
- 如果
-
C1–C4 — GitHub Actions (绝不自动编辑工作流文件)
- 对于每个失败的CI检查项,打印渲染后的(将
templates/github-actions.snippet.yml替换为{{VERSION}}中的policy.json值)。safeChainInstallerVersion - 说明用户应编辑哪个文件(例如)以及该片段应放置在哪个步骤之前。
.github/workflows/ci.yml - 不要对工作流文件执行编辑或写入操作。
- 对于每个失败的CI检查项,打印渲染后的
-
G1 — 未安装Safe Chain
- 打印:,后跟官方安装命令和链接
Safe Chain不在PATH中。请使用以下命令安装:。https://github.com/AikidoSec/safe-chain#installation - 不要执行安装命令。
- 打印:
每个修复应用后,静默重新运行该单项检查并确认现在已通过。如果仍失败,说明原因并停止循环。
Phase 4 — Final summary
阶段4 — 最终总结
Print:
- Updated pass/fail counts after fixes.
- A one-line list of files changed in the repo (use if the cwd is a git repo, else list paths you wrote to).
git diff --stat - Call out separately if you touched it — it is not in the repo.
~/.safe-chain/config.json - If C1–C4 had failures, remind the user that CI workflow edits are still pending (you printed the snippet but did not apply it).
打印:
- 修复后的通过/失败计数。
- 仓库中已更改文件的单行列表(如果当前工作目录是git仓库,使用,否则列出已写入的路径)。
git diff --stat - 如果修改了,单独指出——该文件不在仓库中。
~/.safe-chain/config.json - 如果C1–C4存在失败项,提醒用户CI工作流编辑仍待完成(已打印代码片段但未应用)。
Templates and policy
模板与策略
Available in this skill directory:
- — version pins and threshold values. Always load before rendering templates.
policy.json - — full recommended
templates/npmrcbody..npmrc - — keys to merge into
templates/pnpm-workspace.snippet.yaml.pnpm-workspace.yaml - — keys to merge into
templates/yarnrc.snippet.yml..yarnrc.yml - — keys to merge into
templates/bunfig.snippet.toml.bunfig.toml - — the "Security setup (required)" block.
templates/contributing.snippet.md - — Safe Chain + frozen install steps. Substitute
templates/github-actions.snippet.ymlfrom{{VERSION}}before showing.policy.json#safeChainInstallerVersion
Templates are written verbatim into user repos. Do not paraphrase them.
本技能目录中提供以下内容:
- — 版本固定和阈值。渲染模板前务必加载。
policy.json - — 推荐的完整
templates/npmrc内容。.npmrc - — 需合并到
templates/pnpm-workspace.snippet.yaml中的键。pnpm-workspace.yaml - — 需合并到
templates/yarnrc.snippet.yml中的键。.yarnrc.yml - — 需合并到
templates/bunfig.snippet.toml中的键。bunfig.toml - — “安全设置(必填)”模块。
templates/contributing.snippet.md - — Safe Chain + 冻结安装步骤。展示前需将
templates/github-actions.snippet.yml替换为{{VERSION}}的值。policy.json#safeChainInstallerVersion
模板将原封不动写入用户仓库。请勿改写模板内容。