_ _
__| | ___ _ __ ___ __ _ _ _ __ _ _ __ __| |
/ _` |/ _ \ '_ \/ __|/ _` | | | |/ _` | '__/ _` |
| (_| | __/ |_) \__ \ (_| | |_| | (_| | | | (_| |
\__,_|\___| .__/|___/\__, |\__,_|\__,_|_| \__,_|
|_| |___/
Guard your dependencies against supply chain attacks. Single static binary, zero Rust crate dependencies.
By [arnica]
DepsGuard looks for npm, pnpm, yarn, bun, uv, pip, poetry, and aube on your machine, reads their config files, compares them to recommended supply-chain settings, and can apply fixes interactively. It also scans for Renovate and Dependabot configs in your repos. It never runs package installs; it only edits config files you approve, and it writes backups before any change.
scan subcommand for read-only reportingrestore subcommand to pick a backup and roll back a file| Area | Details |
|---|---|
| Language | Rust (MSRV 1.74, see Cargo.toml) |
| CLI / TUI | src/main.rs, src/ui.rs, src/term.rs |
| Config logic | src/manager.rs, src/fix.rs |
| Website | Static site under docs/ (separate from the binary) |
Each GitHub Release includes archives for:
x86_64 (glibc), x86_64 (musl), aarch64 (glibc)x86_64 ZIP containing depsguard.exeDownload the archive for your platform, unpack it, and put the binary on your PATH.
Verify integrity using the matching .sha256 file next to each asset on the release page.
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
# Homebrew
brew install depsguard
DepsGuard is in homebrew-core, so no custom tap is required.
Migrating from the old
arnica/depsguardtap? Switch to the core formula once:
bash brew uninstall depsguard brew untap arnica/depsguard brew update brew install depsguard
# WinGet
winget install Arnica.DepsGuard
# Scoop
scoop bucket add depsguard https://github.com/arnica/depsguard
scoop install depsguard
Or download manually via 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
cargo install depsguard
Requires a Rust toolchain with cargo.
If your organization ships DepsGuard via Homebrew, Scoop, or WinGet, use their instructions. Setting up or automating those channels (Homebrew core PRs, buckets, WinGet PRs, CI secrets) is maintainer documentation; see AGENTS.md under Release & distribution.
| Channel | Linux | macOS | Windows | Install command |
|---|---|---|---|---|
| APT (custom repo) | yes | no | no | sudo apt install depsguard (after repo setup above) |
| crates.io | yes | yes | yes | cargo install depsguard |
| Homebrew (homebrew-core) | yes | yes | no | brew install depsguard |
| Scoop (custom bucket) | no | no | yes | scoop bucket add depsguard https://github.com/arnica/depsguard ; scoop install depsguard |
| WinGet | no | no | yes | winget install Arnica.DepsGuard |
Use whichever channel you installed with:
| Channel | Upgrade command |
|---|---|
| Homebrew | brew update && brew upgrade depsguard |
| APT (custom repo) | sudo apt update && sudo apt install --only-upgrade depsguard |
| crates.io | cargo install --force depsguard (reinstalls the latest release) |
| Scoop | scoop update && scoop update depsguard |
| WinGet | winget upgrade Arnica.DepsGuard |
Check your installed version any time with depsguard --version, and see the releases page for the newest version.
git clone https://github.com/arnica/depsguard.git
cd depsguard
cargo build --release
The binary is target/release/depsguard (.exe on Windows). Rust 1.74+ is required.
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 to launch the interactive TUI. It scans your system and shows a table of findings. Press any key to continue to the fix selector. Repo-level config discovery starts from the current directory and searches downward. Use depsguard scan for a read-only report, or depsguard --no-search to skip the recursive file search and only check user-level configs.Note: some settings require a minimum version. If your version is too old you'll see:
ℹ min-release-age – requires npm ≥ 11.10 (have 10.2.0). Upgrade withnpm install -g npm@latestand re-run.
↑ ↓ to move through the list (^u ^d to page). Press Space to toggle a fix on or off. Use quick-filter keys to bulk-select by file: a all, n .npmrc, u uv.toml, etc. – press once to select, again to deselect, a third time to clear the filter. Press f to show only currently selected fixes.d to see a diff of what will change before you commit to anything.Enter to apply the selected fixes. A timestamped backup is created before any file is written.depsguard restore at any time to roll back from the backup list. Press q or Esc to quit.| Manager | Config | Setting | Target | Why |
|---|---|---|---|---|
| npm | ~/.npmrc |
min-release-age |
7 (days) |
Delay brand-new releases (requires npm >= 11.10) |
| npm/pnpm | ~/.npmrc |
ignore-scripts |
true |
Reduce install-script risk (npm honors this in .npmrc; pnpm >= 11 reads it from pnpm-workspace.yaml / global config.yaml, not .npmrc) |
| pnpm | ~/.npmrc |
minimum-release-age |
10080 (minutes) |
Delay new versions by 7 days (pnpm 10.16–10.x only; pnpm >= 11 ignores .npmrc; use pnpm-workspace.yaml) |
| pnpm | global rc (pnpm <= 10) |
minimum-release-age |
10080 (minutes) |
Delay new versions by 7 days (requires pnpm >= 10.16) |
| pnpm | global rc (pnpm <= 10) |
block-exotic-subdeps |
true |
Block untrusted transitive deps (requires pnpm >= 10.26) |
| pnpm | global rc (pnpm <= 10) |
trust-policy |
no-downgrade |
Block provenance downgrades (requires pnpm >= 10.21) |
| pnpm | global rc (pnpm <= 10) |
strict-dep-builds |
true |
Fail on unreviewed build scripts (requires pnpm >= 10.3) |
| pnpm | global rc (pnpm <= 10) |
ignore-scripts |
true |
Block malicious install scripts |
| pnpm | global config.yaml (pnpm >= 11) |
minimumReleaseAge |
10080 (minutes) |
Delay new versions by 7 days |
| pnpm | global config.yaml (pnpm >= 11) |
blockExoticSubdeps |
true |
Block untrusted transitive deps |
| pnpm | global config.yaml (pnpm >= 11) |
trustPolicy |
no-downgrade |
Block provenance downgrades |
| pnpm | global config.yaml (pnpm >= 11) |
strictDepBuilds |
true |
Fail on unreviewed build scripts |
| pnpm | global config.yaml (pnpm >= 11) |
ignoreScripts |
true |
Block malicious install scripts |
| yarn | .yarnrc.yml |
npmMinimalAgeGate |
7d |
Delay new versions by 7 days (requires yarn >= 4.10) |
| pnpm | pnpm-workspace.yaml |
minimumReleaseAge |
10080 (minutes) |
Delay new versions by 7 days (requires pnpm >= 10.16) |
| pnpm | pnpm-workspace.yaml |
strictDepBuilds |
true |
Fail on unreviewed build scripts (requires pnpm >= 10.3) |
| pnpm | pnpm-workspace.yaml |
trustPolicy |
no-downgrade |
Block provenance downgrades (requires pnpm >= 10.21) |
| pnpm | pnpm-workspace.yaml |
blockExoticSubdeps |
true |
Block untrusted transitive deps (requires pnpm >= 10.26) |
| pnpm | pnpm-workspace.yaml |
ignoreScripts |
true |
Block malicious install scripts (requires pnpm >= 10.16) |
| bun | ~/.bunfig.toml |
install.minimumReleaseAge |
604800 (seconds) |
~7 day delay (requires bun >= 1.3) |
| aube | ~/.npmrc |
minimumReleaseAge |
10080 (minutes) |
Delay new versions by 7 days |
| uv | uv.toml |
exclude-newer |
7 days |
Delay new publishes (requires uv >= 0.9.17) |
| pip | pip.conf ([install]) |
uploaded-prior-to |
P7D (7 days) |
Delay new publishes (requires pip >= 26.1) |
| poetry | config.toml ([solver]) |
min-release-age |
7 (days) |
Delay new publishes (requires poetry >= 2.4) |
| renovate | renovate.json etc. |
minimumReleaseAge |
7 days |
Delay dependency update PRs by 7 days |
| dependabot | .github/dependabot.yml |
cooldown.default-days |
7 |
Delay dependency update PRs by 7 days |
| Manager | Linux | macOS | Windows |
|---|---|---|---|
| npm/pnpm/aube | ~/.npmrc |
~/.npmrc |
%USERPROFILE%\.npmrc |
| pnpm global (pnpm <= 10) | $XDG_CONFIG_HOME/pnpm/rc or ~/.config/pnpm/rc |
$XDG_CONFIG_HOME/pnpm/rc or ~/Library/Preferences/pnpm/rc |
%LOCALAPPDATA%\pnpm\config\rc |
| pnpm global (pnpm >= 11) | $XDG_CONFIG_HOME/pnpm/config.yaml or ~/.config/pnpm/config.yaml |
$XDG_CONFIG_HOME/pnpm/config.yaml or ~/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 or ~/.bunfig.toml |
$XDG_CONFIG_HOME/.bunfig.toml or ~/.bunfig.toml |
%USERPROFILE%\.bunfig.toml |
| uv | $XDG_CONFIG_HOME/uv/uv.toml or ~/.config/uv/uv.toml |
$XDG_CONFIG_HOME/uv/uv.toml or ~/.config/uv/uv.toml |
%APPDATA%\uv\uv.toml |
| pip | $XDG_CONFIG_HOME/pip/pip.conf or ~/.config/pip/pip.conf |
~/Library/Application Support/pip/pip.conf or ~/.config/pip/pip.conf (or $XDG_CONFIG_HOME/pip/pip.conf when set) |
%APPDATA%\pip\pip.ini |
| poetry | $XDG_CONFIG_HOME/pypoetry/config.toml or ~/.config/pypoetry/config.toml |
$XDG_CONFIG_HOME/pypoetry/config.toml (when set) or ~/Library/Application Support/pypoetry/config.toml |
%APPDATA%\pypoetry\config.toml |
| renovate | renovate.json, .renovaterc, .github/renovate.json, etc. |
(same) | (same) |
| dependabot | .github/dependabot.yml |
(same) | (same) |
User-level config files are read from their standard locations (including XDG-based paths where the tool supports them). Repo-level configs are discovered by searching downward from the current directory, skipping known large directories (node_modules, .git, target, Library, .cache, and others) so scans stay fast. Repo-level .npmrc, .yarnrc.yml, pnpm-workspace.yaml, Renovate configs, and Dependabot configs are all searched. pnpm settings can live in ~/.npmrc (pnpm <= 10 only; pnpm >= 11 reads only auth/registry settings from .npmrc), the pnpm global config file (rc on pnpm <= 10, config.yaml on pnpm >= 11), or pnpm-workspace.yaml; DepsGuard checks all three locations independently. For pip, uv, and poetry, DepsGuard resolves the single effective user-level config and reports just that file, rather than flagging shadowed files separately. pip and poetry merge their config files by precedence (the highest-precedence file that set
$ claude mcp add depsguard \
-- python -m otcore.mcp_server <graph>