Gate every npm install, pip install, and cargo add — including the ones your AI agent runs — against the world's CVE feeds before they reach your disk.
$ npm install lodash@4.17.10
refuse: blocked — CVE-2019-10744 (high)
Prototype pollution in lodash <= 4.17.11
suggested safe version: 4.17.21| Project | What it is |
|---|---|
refuse-cli |
PATH shim that wraps npm, pnpm, yarn, pip, cargo, gem, bun, go — refuses to install packages with known CVEs. Also a Claude Code PreToolUse hook. |
refuse |
Self-hostable HTTP server (Hono + SQLite) that ingests OSV, CISA KEV, FIRST EPSS, GHSA, deps.dev, Wolfi and answers /api/v1/check/*. Ships as ghcr.io/refusehq/refuse. |
The CLI talks to the server. Both are Apache-2.0. A hosted variant lives at refuse.dev for teams that don't want to run their own backend.
Open-source. Apache-2.0 in both the CLI and the server. Pick any platform:
macOS / Linux (sha256-verified binary)
curl -sSL https://raw.githubusercontent.com/RefuseHQ/refuse-cli/main/scripts/install.sh | shWindows (PowerShell) (sha256-verified binary)
irm https://raw.githubusercontent.com/RefuseHQ/refuse-cli/main/scripts/install.ps1 | iexFrom source (any platform with Go ≥ 1.21)
go install github.com/RefuseHQ/refuse-cli/cmd/refuse@latestThen point the CLI at a backend. Either self-host the server (next section, single Docker container, no signup) or use the hosted edition:
refuse init # interactive: server URL + API key
refuse install # drop shims into ~/.refuse/bin
npm install express # routed through the gate transparently- On a laptop. Every
npm install, including the ones your IDE's agent runs without asking, gets vetted first. - In CI. Add
refuse check-lockfileto a workflow step — a bad transitive dep fails the build instead of shipping to prod. - In a Dockerfile. Layer install steps go through the same gate; container builds stop at the vulnerable line.
The server is the slow, careful part — pulling vulnerability feeds, computing severity, suggesting safe versions. The CLI is the fast, dumb part — parse argv, ask, allow or block.
The whole server is one container, zero external services, embedded SQLite. Persistent /data volume keeps the vulnerability DB across restarts so first-boot bootstrap (~3 min) only happens once.
# 1. Run the server with persistent storage
docker run -d --name refuse -p 8080:8080 \
-v refuse-data:/data \
ghcr.io/refusehq/refuse:latest
# 2. Wait for it to seed (OSV bulk + KEV + EPSS + GHSA + Wolfi, ~3 min cold)
curl http://localhost:8080/readyz # returns 503 → 200 when ready
# 3. Point the CLI at it and install shims
refuse config set server_url http://localhost:8080
refuse install
npm install express # gated by your local serverSee refuse/docs/self-hosting.md for the production walkthrough (volume backups, API-key lockdown, GHSA token).
PRs welcome — particularly for new package managers, new agent hooks, and new ingestion sources. Each repo has its own CONTRIBUTING.md. Bugs and feature ideas go in the relevant repo's issues; security reports go through GitHub private vulnerability reporting (see each repo's SECURITY.md).