RefuseHQ/refuse-cli

GitHub: RefuseHQ/refuse-cli

通过 PATH shim 拦截 18 个主流包管理器的安装命令,在执行前阻断存在已知 CVE 漏洞的依赖包。

Stars: 2 | Forks: 1

# refuse-cli **封装了 18 个包管理器 —— `npm`、`pnpm`、`yarn`、`bun`、`npx`、`pip`、`pip3`、`uv`、`poetry`、`pipenv`、`pdm`、`pipx`、`cargo`、`gem`、`bundle`、`go`、`composer`、`dotnet` —— 作为 PATH shim,并附带 Claude Code pre-tool-use hook。拒绝安装存在已知 CVE 的软件包。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/52d16eaa94202034.svg)](https://github.com/RefuseHQ/refuse-cli/actions/workflows/ci.yaml) [![Lint](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5569d19c4c202037.svg)](https://github.com/RefuseHQ/refuse-cli/actions/workflows/lint.yaml) [![CodeQL](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/79c4940676202039.svg)](https://github.com/RefuseHQ/refuse-cli/actions/workflows/codeql.yml) [![Release](https://img.shields.io/github/v/release/RefuseHQ/refuse-cli?display_name=tag&sort=semver)](https://github.com/RefuseHQ/refuse-cli/releases) [![Go Reference](https://pkg.go.dev/badge/github.com/RefuseHQ/refuse-cli.svg)](https://pkg.go.dev/github.com/RefuseHQ/refuse-cli) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
``` $ 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 ``` `refuse` 位于你的包管理器之前。每次 `install` 调用都会在运行真实二进制文件之前,交由 [`refuse`](https://github.com/RefuseHQ/refuse) 服务器(自托管)或 [refuse.dev](https://refuse.dev)(托管版)进行审查。如果该软件包存在高于你设定的严重性阈值的安全公告,安装将被阻止,并提示 CVE 及建议的安全版本。 适用场景: - 开发者的笔记本电脑。 - CI runner。 - Docker build stage 内部。 - 作为 [Claude Code](https://www.anthropic.com/claude-code) PreToolUse hook —— 为自主 agent 安装提供同样的拦截机制。 ## 安装 **Homebrew** (macOS): ``` brew install refusehq/tap/refuse ``` **macOS / Linux 上直接使用二进制文件**: ``` curl -sSL https://raw.githubusercontent.com/RefuseHQ/refuse-cli/main/scripts/install.sh | sh ``` **Windows 上直接使用二进制文件** (PowerShell): ``` irm https://raw.githubusercontent.com/RefuseHQ/refuse-cli/main/scripts/install.ps1 | iex ``` **从源码构建**: ``` go install github.com/RefuseHQ/refuse-cli/cmd/refuse@latest ``` **支持平台。** 预编译二进制文件发布于以下平台: | 操作系统 | 架构 | | --- | --- | | macOS | x86_64, arm64 | | Linux | x86_64, arm64, i386, armv6, armv7 | | Windows | x86_64, arm64, i386 | 其他平台可以通过源码执行 `go install`。 ## 快速开始 ``` refuse init # interactive: server URL + API key refuse install # writes shims to ~/.refuse/bin + updates PATH refuse hook install claude-code # PreToolUse hook in ~/.claude/settings.json refuse python-hook install # closes the `python -m pip` bypass (per Python env) ``` 然后像平常一样运行任何命令: ``` npm install express pip install requests cargo add tokio ``` 如果安装是干净的,命令将会通过。如果不是,refuse 将阻止它并告诉你原因。 ## 服务器 CLI 是拦截关卡;服务器是大脑。有两种方式启动后端 —— 任选其一: **托管版** ([refuse.dev](https://refuse.dev)) ``` refuse config set server_url https://mcp.refuse.dev refuse config set api_key rfs_... ``` **自托管版** ([RefuseHQ/refuse](https://github.com/RefuseHQ/refuse) —— Apache-2.0 协议,单一 Docker container,无需注册) ``` docker run -d --name refuse -p 8080:8080 \ -v refuse-data:/data \ ghcr.io/refusehq/refuse:latest refuse config set server_url http://localhost:8080 ``` 服务器会摄取 OSV、CISA KEV、FIRST EPSS、GHSA、deps.dev 和 Wolfi 的数据;首次启动的引导过程约需 3 分钟,之后每 5 分钟进行一次增量更新。当种子数据加载完成后,`GET /readyz` 的状态会从 503 变为 200。两个版本使用相同的 `/api/v1/check/*` API,因此在托管版和自托管版之间切换只需修改一行配置。 ## 支持的包管理器 | 管理器 | 生态系统 | 安装动词 | Lockfile 解析 | | --- | --- | --- | --- | | `npm` | npm | `install`, `i`, `add` | `package-lock.json` | | `pnpm` | npm | `install`, `add` | `pnpm-lock.yaml` | | `yarn` (classic + Berry) | npm | `add`, `install` | `yarn.lock` | | `bun` | npm | `install`, `add` | `bun.lockb` / `bun.lock` | | `pip` / `pip3` | PyPI | `install`, `install -r` | `requirements.txt` | | `cargo` | crates.io | `add`, `install` | `Cargo.lock` | | `gem` | RubyGems | `install` | `Gemfile.lock` | | `go` | Go modules | `get`, `install` | `go.sum` | ## 支持的 Agent Hook | Agent | 状态 | | --- | --- | | Claude Code | ✓ 支持 | | Cursor | 已纳入追踪 | | Continue | 已纳入追踪 | | Aider | 已纳入追踪 | | Codex CLI | 已纳入追踪 | | Cline | 已纳入追踪 | 欢迎提交 PR —— 请参阅 [`internal/hook/claudecode.go`](./internal/hook/claudecode.go) 作为参考。 ## 命令 | 命令 | 功能 | | --- | --- | | `refuse init` | 首次设置向导 | | `refuse install` | 为受支持的包管理器安装 shim | | `refuse uninstall` | 移除 shim 并还原 shell-rc 修改 | | `refuse hook install ` | 为 `` 写入 pre-tool-use hook | | `refuse hook remove ` | 移除该 hook | | `refuse hook list` | 显示所有已安装的 hook | | `refuse check [@]` | 一次性检查 | | `refuse check-lockfile ` | 扫描整个 lockfile | | `refuse audit [path]` | 对目录下的每一个 lockfile / Dockerfile / GH-Actions workflow 进行一次性扫描 | | `refuse gate` | 决策引擎 —— shim 和 hook 会通过 stdin 调用它 | | `refuse pip-gate` | 针对 pip 参数语法的 `refuse gate` 变体;由 pip shim 调用。 | | `refuse config show \| set \| get` | 管理 `~/.refuse/config.yaml` | | `refuse status` | 诊断安装状态 | | `refuse doctor` | 验证 PATH / hook / 服务器连通性 | ``` refuse audit # walk the repo, scan lockfiles + Dockerfiles + workflows refuse audit --json > out.json ``` ## 配置 使用 `refuse config set `,或者直接编辑 `~/.refuse/config.yaml`: ``` server_url: http://localhost:8080 # or https://mcp.refuse.dev api_key: rfs_... # optional, required for hosted policy: severity_threshold: high # low | medium | high | critical fail_closed: false # true = block if server unreachable (default false → fail open with stderr warning) allow_yanked: false # allow yanked versions when no advisory matches allow_prerelease: false # allow prerelease versions override_env: REFUSE_ALLOW_VULNERABLE # env var that forces a block to pass through ``` 环境变量会覆盖文件配置(在 CI 中非常有用): - `REFUSE_SERVER_URL` - `REFUSE_API_KEY` - `REFUSE_POLICY` —— 设置 `severity_threshold` - `REFUSE_FAIL_CLOSED` —— 设置为 `1`/`true` 以启用 - `REFUSE_ALLOW_VULNERABLE` —— 设置为 `1`/`true` 以放行单次安装 - `REFUSE_TIMEOUT_MS` —— HTTP 超时时间(毫秒,默认为 `8000`) - `REFUSE_NO_GATE` —— 设置为 `1` 将在下次调用时完全跳过拦截关卡(用于调试) ### 针对单条命令绕过拦截关卡 在任何被封装的命令后追加 `--no-refuse` 即可仅跳过一次拦截关卡。 refuse 会在运行真正的管理器之前剥离该 flag: ``` npm install lodash@4.17.10 --no-refuse # runs the real npm, ungated pip install pyyaml==5.3 --no-refuse ``` 这相当于一次性的 `REFUSE_NO_GATE=1`,不过是内联使用。此功能仅适用于通过 PATH shim(交互式使用)的场景 —— agent PreToolUse hook 会忽略它,因此自主 agent 无法绕过其自身的拦截关卡。 ## 强制执行层 —— pre-commit + CI PATH shim 是便捷的第一道防线,但任何绕过它的操作(如 `python -m pip`、`uv`、绝对路径调用、`conda install`、不继承 shim PATH 的 Dockerfile layer)都不会被拦截。**确定性**拦截关卡是 `refuse check-lockfile` —— 无论依赖是如何被引入的,它都会检查已解析的清单文件。 将其接入 pipeline 的两端: ### Pre-commit (本地) 防止带有漏洞的 lockfile 在一开始就被提交。在你的项目 `.pre-commit-config.yaml` 中配置: ``` repos: - repo: https://github.com/RefuseHQ/refuse-cli rev: # pin a refuse release — see https://github.com/RefuseHQ/refuse-cli/releases hooks: - id: refuse-check # Optional, heavier — only on push: - id: refuse-check-installed-pip ``` `refuse-check` 会扫描提交中发生变更的每一个常见 lockfile(`package-lock.json`、`yarn.lock`、`pnpm-lock.yaml`、`requirements.txt`、`Pipfile.lock`、`poetry.lock`、`pdm.lock`、`uv.lock`、`Cargo.lock`、`Gemfile.lock`、`go.sum`、`composer.lock`、`pom.xml`、`*.csproj`、`mix.lock`、`pubspec.lock`),如果命中任何漏洞即中止提交。 `refuse-check-installed-pip` 仅在 `pre-push` 时运行,并将 `pip freeze` 的输出通过管道传给 `refuse check-lockfile`,用于捕获通过 `python -m pip`、`uv pip` 或 `conda install` 引入的依赖。 ### GitHub Actions (CI) 使用内置的 composite action: ``` # .github/workflows/ci.yaml jobs: refuse: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: RefuseHQ/refuse-cli@v1 with: api-key: ${{ secrets.REFUSE_API_KEY }} # lockfiles: | # optional override — auto-discovers if blank # package-lock.json # requirements.txt ``` 自动发现工作区中每一个受支持的 lockfile,并在命中漏洞时让构建失败。详见 [`action.yml`](./action.yml)。 | 输入项 | 默认值 | 必填 | 描述 | | --- | --- | --- | --- | | `server-url` | `https://mcp.refuse.dev` | 否 | refuse 服务器 URL(用于自托管覆盖)。 | | `api-key` | 无 | 否 | refuse API key (`rfs_...`)。托管版必填;本地自托管可选。 | | `lockfiles` | 自动发现 | 否 | 以换行符分隔的 lockfile 路径列表。如果为空,将自动发现常见格式。 | | `version` | `latest` | 否 | 要安装的 refuse-cli 版本。 | | `severity` | 无 | 否 | 严重性底线 (`low` \| `medium` \| `high` \| `critical`)。 | | `fail-on-error` | `true` | 否 | 遇到服务器/网络错误时让工作流失败。设为 `false` 则放行。 | ### 一次性 / 任意扫描 ``` # 扫描显式 lockfile refuse check-lockfile package-lock.json # 扫描当前已安装的 pip 集合(捕获 `python -m pip` / conda) pip freeze | refuse check-lockfile --filename=requirements.txt /dev/stdin ``` ## 安全性 安全策略:[SECURITY.md](./SECURITY.md)。请通过 [hello@refuse.dev](mailto:hello@refuse.dev) 私下报告。 ## 许可证 [Apache License 2.0](./LICENSE) © RefuseHQ。
标签:DevSecOps, EVTX分析, 上游代理, 依赖管理, 日志审计, 漏洞防护, 请求拦截, 软件供应链安全, 远程方法调用