```text
_ _
| | ___ _ __ ___ __ _ _ _ __ _ _ __ | |
/
|/ _ \ '_ \/ __|/ _ | | | |/ | '__/ _ |
| (| | __/ |) _ \ (| | || | (| | | | (| |
_,_|_| ./|/_, |_,|_,|| _,|
|| |___/
保护你的依赖项免受供应链攻击。**单个静态二进制文件,零 Rust crate 依赖。**
由 **[[arnica](https://arnica.io?utm_source=depsguard&utm_medium=referral&utm_campaign=community)]**
## 目录
- [概述](#overview)
- [安装](#install)
- [使用](#usage)
- [检查内容](#what-gets-checked)
- [配置文件位置](#config-file-locations)
- [紧急安全修复](#urgent-security-fix)
- [备份与恢复](#backups-and-restore)
- [工作原理](#how-it-works)
- [故障排除](#troubleshooting)
- [帮助与反馈](#help--feedback)
- [指南](#guides)
- [另请参阅](#see-also)
- [许可证](#license)
## 概述
DepsGuard 会在你的机器上查找 **npm**、**pnpm**、**yarn**、**bun**、**uv**、**pip**、**poetry** 和 **aube**,读取它们的配置文件,将其与推荐的供应链设置进行比较,并可以**交互式应用修复**。它还会扫描你仓库中的 **Renovate** 和 **Dependabot** 配置。它从不运行包安装;它只编辑你批准的配置文件,并且在任何更改前都会写入**备份**。
### 主要特性
- 交互式 TUI:扫描、审查、切换修复、应用
- `scan` 子命令用于只读报告
- `restore` 子命令用于选择备份并回滚文件
- 跨平台:Linux、macOS、Windows
- 无捆绑的第三方 Rust crate(标准库 + 少量用于终端的平台 FFI)
### 技术栈
| 领域 | 详情 |
|------|---------|
| 语言 | Rust(MSRV **1.74**,见 `Cargo.toml`) |
| CLI / TUI | `src/main.rs`、`src/ui.rs`、`src/term.rs` |
| 配置逻辑 | `src/manager.rs`、`src/fix.rs` |
| 网站 | `docs/` 下的静态站点(与二进制文件分开) |
## 安装
### 预构建二进制文件
每个 [GitHub Release](https://github.com/arnica/depsguard/releases) 包含以下平台的归档:
- Linux:`x86_64`(glibc)、`x86_64`(musl)、`aarch64`(glibc)
- macOS:Intel 和 Apple Silicon
- Windows:包含 `depsguard.exe` 的 `x86_64` ZIP
下载你平台的归档,解压,并将二进制文件放入你的 `PATH` 中。
使用发布页面上每个资产旁边的匹配 `.sha256` 文件验证完整性。
### 按平台安装
#### Linux(通过 APT 在 Debian/Ubuntu 上)```bash
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://depsguard.com/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/depsguard.gpg
echo "deb [arch=amd64,arm64 signed-by=/etc/apt/keyrings/depsguard.gpg] https://depsguard.com/apt stable main" | sudo tee /etc/apt/sources.list.d/depsguard.list >/dev/null
sudo apt update
sudo apt install depsguard
brew install depsguard
DepsGuard 已在 [homebrew-core](https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/d/depsguard.rb) 中,因此无需自定义 tap。
> **从旧的 `arnica/depsguard` tap 迁移?** 请切换到 core 公式:
>
> ```bash
> brew uninstall depsguard
> brew untap arnica/depsguard
> brew update
> brew install depsguard
> ```
#### Windows```powershell
# WinGet
winget install Arnica.DepsGuard
# Scoop
scoop bucket add depsguard https://github.com/arnica/depsguard
scoop install depsguard
或者通过 PowerShell 手动下载:```powershell $zip = "$env:TEMP\depsguard.zip" Invoke-WebRequest -Uri "https://github.com/arnica/depsguard/releases/latest/download/depsguard-x86_64-pc-windows-msvc.zip" -OutFile $zip Expand-Archive -LiteralPath $zip -DestinationPath "$env:TEMP\depsguard" -Force Copy-Item "$env:TEMP\depsguard\depsguard.exe" "$HOME\AppData\Local\Microsoft\WindowsApps\depsguard.exe" -Force depsguard.exe --help
### crates.io```bash
cargo install depsguard
需要一个安装了 cargo 的 Rust 工具链。
如果你的组织通过 Homebrew、Scoop 或 WinGet 分发 DepsGuard,请使用它们的说明。设置或自动化这些渠道(Homebrew core PRs、buckets、WinGet PRs、CI secrets)属于维护者文档;请参阅 AGENTS.md 中的 发布与分发 部分。
使用你安装时所用的渠道:
随时使用 depsguard --version 检查已安装的版本,并查看发布页面以获取最新版本。
git clone https://github.com/arnica/depsguard.git cd depsguard cargo build --release
二进制文件位于 `target/release/depsguard`(Windows 上为 `.exe`)。需要 Rust **1.74+**。
## 用法```bash
depsguard # interactive: scan, choose fixes, apply
depsguard scan # report only; no writes (exits 1 if action is needed)
depsguard --no-search # skip recursive file search, check local configs only
depsguard restore # restore from a previous backup
depsguard --help # CLI help
depsguard 以启动交互式 TUI。它会扫描您的系统并显示一份结果表格。按任意键继续进入修复选择器。仓库级配置发现从当前目录开始向下搜索。使用 depsguard scan 可生成只读报告,或使用 depsguard --no-search 跳过递归文件搜索,仅检查用户级配置。
注意: 某些设置需要最低版本。如果您的版本过旧,您将看到:
ℹ min-release-age – 需要 npm ≥ 11.10(当前为 10.2.0)。 使用npm install -g npm@latest升级并重新运行。
↑ ↓ 在列表中移动(^u ^d 翻页)。按 Space 切换修复的开关状态。使用快速过滤键按文件批量选择:a 全部,n .npmrc,u uv.toml 等——按一次选择,再按一次取消选择,第三次清除过滤。按 仅显示当前选中的修复。用户级配置文件从标准位置读取(包括工具支持的基于 XDG 的路径)。仓库级配置通过从当前目录向下搜索发现,跳过已知的大目录(node_modules、.git、target、Library、.cache 等),以保持扫描快速。仓库级的 .npmrc、.yarnrc.yml、pnpm-workspace.yaml、Renovate 配置和 Dependabot 配置均被搜索。pnpm 设置可以存在于 ~/.npmrc(仅 pnpm <= 10;pnpm >= 11 仅从 .npmrc 读取认证/注册表设置)、pnpm 全局配置文件(pnpm <= 10 为 rc,pnpm >= 11 为 config.yaml)或 pnpm-workspace.yaml 中;DepsGuard 独立检查所有三个位置。对于 pip、uv 和 poetry,DepsGuard 解析单个有效的用户级配置,仅报告该文件,而不会单独标记被遮蔽的文件。pip 和 poetry 按优先级合并它们的配置文件(设置冷却期的最高优先级文件获胜,如果均未设置则使用首选位置);uv 读取单个用户文件(当设置了 XDG_CONFIG_HOME 时为 ,否则为 )而不是合并两者。对于 bun,如果存在多个用户级配置文件(例如 XDG 路径和 home 目录路径),DepsGuard 会分别扫描每个现有文件。aube 读取与 npm/pnpm 相同的 (,以分钟为单位),并且也会在发现的仓库级 文件中进行检查;pip 和 poetry 在其用户级配置( / )中被扫描。
如果修补后的版本比您的冷却期更新,请添加一个狭窄的例外,安装修复,然后移除该例外。
首选包特定的例外,而不是降低全局冷却期。这样可以为所有其他依赖保留延迟。
在绕过冷却期之前:
在修改文件之前,DepsGuard 会将备份写入 ~/.depsguard/backups/。
运行 depsguard restore 列出备份并恢复其中一个。
src/ main.rs CLI args, run loop term.rs Raw mode + input (Unix termios / Windows console FFI) manager.rs Detection, scanning, recommendations fix.rs Read/write .npmrc, TOML, YAML; backup/restore ui.rs Banner, tables, selector
- **零第三方 crate**:有意为之,适用于小型安全工具;若更改此策略,请参阅 `AGENTS.md`。
- **颜色** 使用 ANSI 序列;现代终端(例如 Windows Terminal)在 Windows 上受支持。
## 故障排除
| 症状 | 尝试方法 |
|---------|-------------|
| `depsguard: 命令未找到` | 确保安装目录在 `PATH` 中,或使用二进制文件的完整路径。 |
| 写入配置时权限错误 | DepsGuard 仅编辑用户配置文件;以普通用户身份运行,不要提权,除非这些文件由管理员所有。 |
| Windows 上按键无效 | 使用 **Windows Terminal** 或其他支持 VT 的终端;旧版 `cmd.exe` 可能无法处理所有按键。 |
| pnpm 工作区缺失 | 确保 `pnpm-workspace.yaml` 位于你的主目录树中;非常不常见的目录布局可能无法被发现。 |
| `cargo install` 失败 | 通过 [rustup](https://rustup.rs/) 安装 Rust,并使用 Rust **≥ 1.74**。 |
## 帮助与反馈
- [报告 Bug 或请求功能](https://github.com/arnica/depsguard/issues)
- [报告安全漏洞](https://github.com/arnica/depsguard/security/advisories/new)(参见 [`SECURITY.md`](https://github.com/arnica/depsguard/blob/HEAD/SECURITY.md))
- 贡献者的开发工作流位于 [`AGENTS.md`](https://github.com/arnica/depsguard/blob/HEAD/AGENTS.md)。
## 指南
[depsguard.com](https://depsguard.com) 上的深入指南解释了每个加固设置及其防御的供应链攻击:
- [如何防范 npm 供应链攻击](https://depsguard.com/guide/)(完整加固指南)
- [依赖冷却期(最小发布年龄)](https://depsguard.com/cooldown/)
- [使用 ignore-scripts 阻止安装脚本](https://depsguard.com/ignore-scripts/)
- [阻止不受信任的传递依赖(block-exotic-subdeps)](https://depsguard.com/block-exotic-subdeps/)
- [对未经审核的构建脚本失败处理(strict-dep-builds)](https://depsguard.com/strict-dep-builds/)
- [阻止来源降级(trust-policy)](https://depsguard.com/trust-policy/)
- 事件分析: [axios](https://depsguard.com/axios-npm-attack/) · [Shai-Hulud](https://depsguard.com/shai-hulud/) · [TanStack](https://depsguard.com/tanstack-npm-attack/)
## 另请参阅
- [**依赖冷却期**(`cooldowns.dev`)](https://cooldowns.dev/):一个参考指南和配套 Shell 辅助工具(`cooldowns.sh`),专注于**最小发布年龄冷却期**。与 DepsGuard 互补:它在冷却期维度上覆盖更广泛的生态系统(pip、uv、npm、pnpm、Yarn、Bun、Deno、Cargo),而 DepsGuard 覆盖 npm/pnpm/yarn/bun/aube/uv/pip/poetry 以及 Renovate/Dependabot,并增加了其他加固设置(`ignore-scripts`、`block-exotic-subdeps`、`trust-policy`、`strict-dep-builds`),提供交互式 TUI、差异预览和备份/恢复功能。
## 许可证
MIT
---
**链接:** [仓库](https://github.com/arnica/depsguard) · [文档站点](https://depsguard.com)
| 渠道 | Linux | macOS | Windows | 安装命令 |
|---|
| APT(自定义仓库) | yes | no | no | sudo apt install depsguard(完成上述仓库设置后) |
| crates.io | yes | yes | yes | cargo install depsguard |
| Homebrew(homebrew-core) | yes | yes | no | brew install depsguard |
| Scoop(自定义 bucket) | no | no | yes | scoop bucket add depsguard https://github.com/arnica/depsguard ; scoop install depsguard |
| WinGet | no | no | yes | winget install Arnica.DepsGuard |
| 渠道 | 升级命令 |
|---|
| Homebrew | brew update && brew upgrade depsguard |
| APT(自定义仓库) | sudo apt update && sudo apt install --only-upgrade depsguard |
| crates.io | cargo install --force depsguard(重新安装最新版本) |
| Scoop | scoop update && scoop update depsguard |
| WinGet | winget upgrade Arnica.DepsGuard |
fd 查看将会变更的差异(diff),确认无误后再执行。Enter 应用选中的修复。写入任何文件前都会创建带时间戳的备份。depsguard restore 从备份列表中回滚。按 q 或 Esc 退出。| 包管理器 | 配置文件 | 设置项 | 目标值 | 说明 |
|---|
| npm | ~/.npmrc | min-release-age | 7(天) | 延迟全新版本的发布(需要 npm >= 11.10) |
| npm/pnpm | ~/.npmrc | ignore-scripts | true | 降低安装脚本风险(npm 在 .npmrc 中执行此设置;pnpm >= 11 从 pnpm-workspace.yaml 或全局 config.yaml 读取,而非 .npmrc) |
| pnpm | ~/.npmrc | minimum-release-age | 10080(分钟) | 将新版本延迟 7 天(仅 pnpm 10.16–10.x;pnpm >= 11 忽略 .npmrc;请使用 pnpm-workspace.yaml) |
| pnpm | 全局 rc(pnpm <= 10) | minimum-release-age | 10080(分钟) | 将新版本延迟 7 天(需要 pnpm >= 10.16) |
| pnpm | 全局 rc(pnpm <= 10) | block-exotic-subdeps | true | 阻止不受信任的传递依赖(需要 pnpm >= 10.26) |
| pnpm | 全局 rc(pnpm <= 10) | trust-policy | no-downgrade | 阻止来源降级(需要 pnpm >= 10.21) |
| pnpm | 全局 rc(pnpm <= 10) | strict-dep-builds | true | 在未审核的构建脚本上失败(需要 pnpm >= 10.3) |
| pnpm | 全局 rc(pnpm <= 10) | ignore-scripts | true | 阻止恶意安装脚本 |
| pnpm | 全局 config.yaml(pnpm >= 11) | minimumReleaseAge | 10080(分钟) | 将新版本延迟 7 天 |
| pnpm | 全局 config.yaml(pnpm >= 11) | blockExoticSubdeps | true | 阻止不受信任的传递依赖 |
| pnpm | 全局 config.yaml(pnpm >= 11) | trustPolicy | no-downgrade | 阻止来源降级 |
| pnpm | 全局 config.yaml(pnpm >= 11) | strictDepBuilds | true | 在未审核的构建脚本上失败 |
| pnpm | 全局 config.yaml(pnpm >= 11) | ignoreScripts | true | 阻止恶意安装脚本 |
| yarn | .yarnrc.yml | npmMinimalAgeGate | 7d | 将新版本延迟 7 天(需要 yarn >= 4.10) |
| pnpm | pnpm-workspace.yaml | minimumReleaseAge | 10080(分钟) | 将新版本延迟 7 天(需要 pnpm >= 10.16) |
| pnpm | pnpm-workspace.yaml | strictDepBuilds | true | 在未审核的构建脚本上失败(需要 pnpm >= 10.3) |
| pnpm | pnpm-workspace.yaml | trustPolicy | no-downgrade | 阻止来源降级(需要 pnpm >= 10.21) |
| pnpm | pnpm-workspace.yaml | blockExoticSubdeps | true | 阻止不受信任的传递依赖(需要 pnpm >= 10.26) |
| pnpm | pnpm-workspace.yaml | ignoreScripts | true | 阻止恶意安装脚本(需要 pnpm >= 10.16) |
| bun | ~/.bunfig.toml | install.minimumReleaseAge | 604800(秒) | 约 7 天延迟(需要 bun >= 1.3) |
| aube | ~/.npmrc | minimumReleaseAge | 10080(分钟) | 将新版本延迟 7 天 |
| uv | uv.toml | exclude-newer | 7 days | 延迟新发布(需要 uv >= 0.9.17) |
| pip | pip.conf([install]) | uploaded-prior-to | P7D(7 天) | 延迟新发布(需要 pip >= 26.1) |
| poetry | config.toml([solver]) | min-release-age | 7(天) | 延迟新发布(需要 poetry >= 2.4) |
| renovate | renovate.json 等 | minimumReleaseAge | 7 days | 将依赖更新 PR 延迟 7 天 |
| dependabot | .github/dependabot.yml | cooldown.default-days | 7 | 将依赖更新 PR 延迟 7 天 |
| 包管理器 | Linux | macOS | Windows |
|---|
| npm/pnpm/aube | ~/.npmrc | ~/.npmrc | %USERPROFILE%\.npmrc |
| pnpm 全局(pnpm <= 10) | $XDG_CONFIG_HOME/pnpm/rc 或 ~/.config/pnpm/rc | $XDG_CONFIG_HOME/pnpm/rc 或 ~/Library/Preferences/pnpm/rc | %LOCALAPPDATA%\pnpm\config\rc |
| pnpm 全局(pnpm >= 11) | $XDG_CONFIG_HOME/pnpm/config.yaml 或 ~/.config/pnpm/config.yaml | $XDG_CONFIG_HOME/pnpm/config.yaml 或 ~/Library/Preferences/pnpm/config.yaml | %LOCALAPPDATA%\pnpm\config\config.yaml |
| yarn | ~/.yarnrc.yml | ~/.yarnrc.yml | %USERPROFILE%\.yarnrc.yml |
| pnpm | pnpm-workspace.yaml | pnpm-workspace.yaml | pnpm-workspace.yaml |
| bun | $XDG_CONFIG_HOME/.bunfig.toml 或 ~/.bunfig.toml | $XDG_CONFIG_HOME/.bunfig.toml 或 ~/.bunfig.toml | %USERPROFILE%\.bunfig.toml |
| uv | $XDG_CONFIG_HOME/uv/uv.toml 或 ~/.config/uv/uv.toml | $XDG_CONFIG_HOME/uv/uv.toml 或 ~/.config/uv/uv.toml | %APPDATA%\uv\uv.toml |
| pip | $XDG_CONFIG_HOME/pip/pip.conf 或 ~/.config/pip/pip.conf | ~/Library/Application Support/pip/pip.conf 或 ~/.config/pip/pip.conf(或设置 $XDG_CONFIG_HOME 时的 $XDG_CONFIG_HOME/pip/pip.conf) | %APPDATA%\pip\pip.ini |
| poetry | $XDG_CONFIG_HOME/pypoetry/config.toml 或 ~/.config/pypoetry/config.toml | 设置 $XDG_CONFIG_HOME 时的 $XDG_CONFIG_HOME/pypoetry/config.toml 或 ~/Library/Application Support/pypoetry/config.toml | %APPDATA%\pypoetry\config.toml |
| renovate | renovate.json、.renovaterc、.github/renovate.json 等 | 相同 | 相同 |
| dependabot | .github/dependabot.yml | 相同 | 相同 |
$XDG_CONFIG_HOME/uv/uv.toml~/.config/uv/uv.toml~/.npmrcminimumReleaseAge.npmrcpip.confpypoetry/config.toml| 包管理器 | 如何绕过冷却期 |
|---|
| npm | npm install <包名>@<版本> --min-release-age=0 |
| pnpm | 在 pnpm-workspace.yaml 中添加一条到 minimumReleaseAgeExclude 的条目,运行 pnpm add <包名>@<版本>,然后移除该条目。按包名排除适用于 pnpm 10.16+;固定特定版本(<包名>@<版本>)额外需要 pnpm 10.19+。pnpm 没有针对 minimumReleaseAge 的文档化 CLI 覆盖选项。 |
| yarn | 在 .yarnrc.yml 中添加 <包名>(或通配符)到 npmPreapprovedPackages,或运行 YARN_NPM_MINIMAL_AGE_GATE=0s yarn up <包名>@<版本> 一次命令。npmPreapprovedPackages 会将匹配项从所有 Yarn 包门控(而不仅仅是年龄门控)中豁免。 |
| bun | 在仓库级 bunfig.toml 或用户级 ~/.bunfig.toml 中添加 <包名> 到 install.minimumReleaseAgeExcludes,或运行 bun add <包名>@<版本> --minimum-release-age 0。 |
| aube | 在 .npmrc 中添加 <包名> 到 minimumReleaseAgeExclude,或为单次安装设置 AUBE_MINIMUM_RELEASE_AGE=0(或 npm_config_minimum_release_age=0)。 |
| uv | 在 uv.toml 或 pyproject.toml 中添加 "<包名>" = false 到 exclude-newer-package,运行 uv add <包名>==<版本>,然后移除该条目。exclude-newer-package 是一个独立的全局 exclude-newer 截止期的每包覆盖项。uv 的 CLI 接受 --exclude-newer-package PACKAGE=DATE,但不接受 PACKAGE=false。 |
| pip | 运行 pip install <包名>==<版本> --uploaded-prior-to=P0D 进行单次安装。P0D 仅对该命令禁用冷却期;pip 在配置中没有每包排除项。 |
| poetry | 在 poetry.toml/config.toml 中添加 <包名> 到 solver.min-release-age-exclude(逗号分隔),运行 poetry add <包名>@<版本>,然后移除该条目。solver.min-release-age-exclude-source 会将每个包从指定索引中豁免。 |
| Renovate | 安全更新默认已绕过 minimumReleaseAge。对于版本更新,添加一个 packageRules 条目,包含 matchPackageNames: ["<包名>"] 和 minimumReleaseAge: null。 |
| Dependabot | 安全更新默认已绕过 cooldown。对于版本更新,将 <包名> 添加到 cooldown.exclude。 |