
safe-chain v1.5.15
使用 Aikido Safe Chain 防范通过 npm、yarn、pnpm、npx、pnpx、pip、uv 和 poetry 安装的恶意代码。免费使用,无需令牌。
Aikido Safe Chain
- ✅ 在开发者笔记本电脑和 CI/CD 上阻止恶意软件
- ✅ 支持 npm 和 PyPI,更多包管理器即将推出
- ✅ 阻止发布不足 48 小时的包,不会破坏你的构建
- ✅ 无需令牌、免费、不共享构建数据
需要超越 npm 和 PyPI 的保护?
Aikido Device Protection 基于 Safe Chain 构建,将包和扩展安全性扩展到更多生态系统:npm、PyPI、VS Code、Open VSX - (Cursor, Windsurf, Kiro, Vs Codium, ...)、Maven、NuGet、Chrome 扩展、Go、Skills.sh AI 技能、Ruby、Rust 等。
获取集中式策略管理、请求-批准工作流,以及整个组织内每个开发者工作站的可见性。由相同的 Aikido Intel 数据源提供支持。可手动部署,也可通过你的 MDM 工具(Jamf、Fleet 或 Iru)进行管理。
Aikido Safe Chain 支持以下包管理器:
- 📦 npm
- 📦 npx
- 📦 yarn
- 📦 pnpm
- 📦 pnpx
- 📦 rush
- 📦 rushx
- 📦 bun
- 📦 bunx
- 📦 pip
- 📦 pip3
- 📦 uv
- 📦 poetry
- 📦 uvx
- 📦 pipx
- 📦 pdm
用法

安装
通过安装脚本即可轻松安装 Aikido Safe Chain。
Unix/Linux/macOS```shell
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh
&& echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c -
&& sh /tmp/install-safe-chain.sh
&& rm /tmp/install-safe-chain.sh
### Windows (PowerShell)```powershell
$installer = Join-Path $env:TEMP "install-safe-chain.ps1"
Invoke-WebRequest "https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.ps1" -OutFile $installer -UseBasicParsing
$expectedHash = "5FC22EEF74814BEF6828AA07C0EAEC79598F343F98B94A4ACAB823769AD56DA1"
if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne $expectedHash) {
Remove-Item $installer -ErrorAction SilentlyContinue
throw "Checksum verification failed for install-safe-chain.ps1"
}
& $installer
Remove-Item $installer
上面的安装命令总是引用特定的发布版本。要安装其他版本,请将版本号替换为您想要的版本号。所有可用版本均可在发布页面上找到。
下载完整性
安装脚本从带版本号的发布 URL(releases/download/1.5.15/...)提供。GitHub 发布是不可变的——一旦工件发布到带版本号的 URL,就不能被修改或替换,因此您下载的文件可以保证与发布时完全一致。
验证安装
-
❗重启您的终端以开始使用 Aikido Safe Chain。
- 这一步至关重要,因为它确保 npm、npx、yarn、pnpm、pnpx、rush、rushx、bun、bunx、pip、pip3、poetry、uv、uvx、pipx 和 pdm 的 shell 别名被正确加载。如果您不重启终端,这些别名将不可用。
-
验证安装,运行以下验证命令: ```shell npm safe-chain-verify pnpm safe-chain-verify pip safe-chain-verify uv safe-chain-verify
Any other supported package manager: {packagemanager} safe-chain-verify
- 输出应显示 "OK: Safe-chain works!",确认 Aikido Safe Chain 已正确安装并运行。
-
(可选)测试恶意软件拦截:尝试安装一个测试包:
对于 JavaScript/Node.js: ```shell npm install safe-chain-test
对于 Python: ```shell pip3 install safe-chain-pi-test
- 输出应显示 Aikido Safe Chain 正在阻止安装这些测试包,因为它们被标记为恶意软件。
在运行 `npm`、`npx`、`yarn`、`pnpm`、`pnpx`、`rush`、`rushx`、`bun`、`bunx`、`pip`、`pip3`、`uv`、`uvx`、`poetry`、`pipx` 和 `pdm` 命令时,Aikido Safe Chain 会自动检查你尝试安装的包中是否存在恶意软件。它还会在你使用 pip 时拦截相应的 Python 模块调用(例如,`python -m pip install ...`、`python3 -m pip download ...`)。如果检测到任何恶意软件,它会提示你退出该命令。
你可以通过运行以下命令检查已安装的版本:```shell
safe-chain --version
工作原理
恶意软件拦截
Aikido Safe Chain 通过运行一个轻量级代理服务器来拦截来自 npm 仓库和 PyPI 的软件包下载。当您运行 npm、npx、yarn、pnpm、pnpx、rush、rushx、bun、bunx、pip、pip3、uv、uvx、poetry、pipx 或 pdm 命令时,所有软件包下载都会通过这个本地代理进行路由,代理会实时对照 Aikido Intel - Open Sources Threat Intelligence 对软件包进行验证。如果在任何软件包(包括深层依赖)中检测到恶意软件,代理会在恶意代码到达您的机器之前阻止下载。
最低包龄
Safe Chain 对受支持的生态系统执行最低包龄检查。
不同生态系统的执行方式有所不同:
- 基于 npm 的包管理器:
- 在正常的包解析过程中,Safe Chain 会从仓库返回的包元数据中抑制那些比配置的最低包龄更新的版本
- 对于绕过该元数据流程的直接包下载请求,Safe Chain 可以使用缓存的新发布包列表直接阻止该请求
- Python 包管理器:
- 在包解析过程中,Safe Chain 会从 PyPI 元数据响应中抑制过新的文件和发行版
- 对于绕过该元数据流程的直接包下载请求,Safe Chain 可以使用缓存的新发布包列表直接阻止该请求
默认情况下,最低包龄为 48 小时。这在新发布的包最有可能包含未检测到威胁的关键时期内提供了额外的安全层。您可以配置此阈值或完全绕过此保护——请参阅下方的 最低包龄配置 部分。
Shell 集成
Aikido Safe Chain 与您的 shell 集成,以便在使用 npm、npx、yarn、pnpm、pnpx、rush、rushx、bun、bunx 以及 Python 包管理器(pip、uv、uvx、poetry、pipx、pdm)时提供无缝体验。它为这些命令设置别名,使其由 Aikido Safe Chain 命令包装,在执行原始命令之前管理代理服务器。我们目前支持:
- ✅ Bash
- ✅ Zsh
- ✅ Fish
- ✅ PowerShell
- ✅ PowerShell Core
有关 shell 集成的更多信息,请参阅 shell 集成文档。
卸载
要卸载 Aikido Safe Chain,请使用我们的一行卸载命令:
Unix/Linux/macOS```shell
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/uninstall-safe-chain.sh | sh
### Windows (PowerShell)```powershell
iex (iwr "https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/uninstall-safe-chain.ps1" -UseBasicParsing)
❗卸载后请重启终端,以确保所有别名均已移除。
配置
日志记录
你可以使用 --safe-chain-logging 标志或 SAFE_CHAIN_LOGGING 环境变量来控制 Aikido Safe Chain 的输出。
配置选项
你可以通过多种来源设置日志级别(按优先级顺序):
-
CLI 参数(最高优先级):
-
--safe-chain-logging=silent- 抑制 Aikido Safe Chain 的所有输出,除非检测到恶意软件被阻止。包管理器的输出照常写入 stdout,Safe Chain 仅在阻止恶意软件并导致进程退出时写入一条简短消息。npm install express --safe-chain-logging=silent -
--safe-chain-logging=verbose- 启用来自 Aikido Safe Chain 的详细诊断输出。有助于排查问题或了解 Safe Chain 在后台执行的操作。npm install express --safe-chain-logging=verbose
-
-
环境变量: ```shell export SAFE_CHAIN_LOGGING=verbose npm install express
Valid values: silent, normal, verbose
这有助于为终端会话或 CI/CD 环境中的所有包管理器命令设置默认日志级别。
文件日志
你可以使用 --safe-chain-log-file 标志或 SAFE_CHAIN_LOG_FILE 环境变量将 Aikido Safe Chain 的输出同时写入日志文件。文件日志默认处于禁用状态,设置路径后即启用。文件格式(--safe-chain-log-file-format)和详细程度(--safe-chain-log-file-verbosity)独立于终端输出进行控制。
配置选项
通过以下任一方式设置(按优先级顺序):
- CLI 参数(最高优先级): ```shell
npm install express
--safe-chain-log-file=~/safe-chain.log
--safe-chain-log-file-format=plain
--safe-chain-log-file-verbosity=normal - 环境变量: ```shell
export SAFE_CHAIN_LOG_FILE=~/safe-chain.log
export SAFE_CHAIN_LOG_FILE_FORMAT=plain
export SAFE_CHAIN_LOG_FILE_VERBOSITY=normal
- 配置文件 (
~/.safe-chain/config.json): ```json { "logFile": "~/safe-chain.log", "logFileFormat": "plain", "logFileVerbosity": "normal" }
logFileFormat — json(默认)或 plain。
logFileVerbosity — silent、normal 或 verbose(默认)。独立于 --safe-chain-logging。
最小包年龄
你可以配置软件包必须存在多长时间后,Safe Chain 才允许安装它们。默认情况下,软件包必须至少存在 48 小时才能被安装。
对于基于 npm 的包管理器,此检查目前有两种执行模式:
- Safe Chain 在正常依赖解析过程中,从包元数据中抑制过于年轻的版本。
- Safe Chain 在直接包下载请求与缓存的“新发布包列表”匹配时,阻止这些请求。
对于 Python 包管理器,此检查目前有两种执行模式:
- Safe Chain 在依赖解析过程中,从 PyPI 元数据中抑制过于年轻的文件和发行版。
- Safe Chain 在直接包下载请求与缓存的“新发布包列表”匹配时,阻止这些请求。
配置选项
你可以通过多个来源设置最小包年龄(按优先级顺序):
- CLI 参数(最高优先级): ```shell
npm install express --safe-chain-minimum-package-age-hours=48
- 环境变量: ```shell
export SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS=48
npm install express
- 配置文件 (
~/.safe-chain/config.json): ```json { "minimumPackageAgeHours": 48 }
排除软件包
通过环境变量或配置文件将受信任的软件包排除在最低年龄过滤之外(两者会合并)。使用 @scope/* 来信任某个组织的所有软件包:```shell
export SAFE_CHAIN_MINIMUM_PACKAGE_AGE_EXCLUSIONS="@aikidosec/*"
I received no content to translate. The message ends with "INPUT:" but contains no actual Markdown text. Please provide the chunk content, and I will translate it according to the rules.```json
{
"npm": {
"minimumPackageAgeExclusions": ["@aikidosec/*"]
},
"pip": {
"minimumPackageAgeExclusions": ["requests"]
}
}
自定义仓库
配置 Safe Chain 以扫描来自自定义或私有仓库的包。
支持的生态系统:
- Node.js
- Python
配置选项
你可以通过环境变量或配置文件设置自定义仓库。两种来源会合并在一起。
- 环境变量(逗号分隔): ```shell
export SAFE_CHAIN_NPM_CUSTOM_REGISTRIES="npm.company.com,registry.internal.net"
export SAFE_CHAIN_PIP_CUSTOM_REGISTRIES="pip.company.com,registry.internal.net"
- 配置文件 (
~/.safe-chain/config.json): ```json { "npm": { "customRegistries": ["npm.company.com", "registry.internal.net"] }, "pip": { "customRegistries": ["pip.company.com", "registry.internal.net"] } }
PYPI 配置文件
如果你依赖 pip.conf 文件进行 pip 配置,你必须通过 PIP_CONFIG_FILE 环境变量显式地将 pip 指向该文件,以便 Safe Chain 能够合并它。
Safe Chain 在其 MITM 代理后面运行 pip,并写入一个临时的 pip 配置文件以注入其证书和代理设置。当设置了 PIP_CONFIG_FILE 时,Safe Chain 会将它的设置合并到你的配置文件副本中(你的原始文件绝不会被修改),从而保留你的 index-url、凭据和其他选项。如果未设置 PIP_CONFIG_FILE,pip 的用户级配置(例如 ~/.config/pip/pip.conf)可能会被 Safe Chain 的临时文件覆盖,你的设置将不会被读取。
恶意软件列表基础 URL
配置 Safe Chain 从自定义镜像 URL 获取恶意软件数据库和新软件包列表。这样你就可以托管自己的 Aikido 恶意软件数据库副本。
配置选项
你可以通过多个来源设置恶意软件列表基础 URL(按优先级顺序):
- CLI 参数(最高优先级): ```shell
npm install express --safe-chain-malware-list-base-url=https://your-mirror.com
- 环境变量: ```shell
export SAFE_CHAIN_MALWARE_LIST_BASE_URL=https://your-mirror.com
npm install express
- 配置文件 (
~/.safe-chain/config.json): ```json { "malwareListBaseUrl": "https://your-mirror.com" }
基 URL 应指向一个镜像 https://malware-list.aikido.dev/ 结构的服务器,包括以下路径:
/malware_predictions.json(JavaScript 生态恶意软件数据库)/malware_pypi.json(Python 生态恶意软件数据库)/releases/npm.json(JavaScript 新软件包列表)/releases/pypi.json(Python 新软件包列表)
项目配置文件
除了主目录配置文件(~/.safe-chain/config.json)之外,Safe Chain 还支持项目配置文件,以便设置可以提交到仓库并与团队共享,而不是每台机器单独配置。
在仓库根目录的 .aikido 文件中添加一个 safe-chain: 部分(该文件与其他 Aikido 工具使用的文件相同,Safe Chain 只读取自己的 safe-chain: 部分并忽略其余内容)。找到该部分后,其设置会合并到主目录配置文件之上:项目配置中设置的值优先,数组(如 customRegistries)会合并两个文件中的内容,而不是互相替换。
只能从项目配置文件中设置以下设置:```yaml safe-chain: minimumPackageAgeHours: 48 npm: customRegistries: - npm.company.com minimumPackageAgeExclusions: - "@aikidosec/*" pip: customRegistries: - pip.company.com minimumPackageAgeExclusions: - requests
诸如 `scanTimeout`、`malwareListBaseUrl` 以及 `logFile*` 之类的设置无法通过项目配置文件进行设置——它们只能来自你的主目录配置、CLI 参数或环境变量。
## 自定义安装目录
默认情况下,Safe Chain 会安装到 `~/.safe-chain`。你可以通过向安装程序传递显式的安装目录来更改此路径。这对于系统级安装(例如 Docker 镜像内)或需要避免与其他工具冲突时非常有用。
设置后,所有 Safe Chain 数据(二进制文件、shim、脚本、配置)都会放置在自定义目录下,而不是 `~/.safe-chain`。
### Unix/Linux/macOS```shell
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh \
&& echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c - \
&& sh /tmp/install-safe-chain.sh --install-dir /usr/local/.safe-chain \
&& rm /tmp/install-safe-chain.sh
Windows```powershell
$installer = Join-Path $env:TEMP "install-safe-chain.ps1" Invoke-WebRequest "https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.ps1" -OutFile $installer -UseBasicParsing $expectedHash = "5FC22EEF74814BEF6828AA07C0EAEC79598F343F98B94A4ACAB823769AD56DA1" if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne $expectedHash) { Remove-Item $installer -ErrorAction SilentlyContinue throw "Checksum verification failed for install-safe-chain.ps1" } & $installer -InstallDir 'C:\ProgramData\safe-chain' Remove-Item $installer
# 在 CI/CD 中的使用
你可以通过将 Aikido Safe Chain 集成到构建流程中,来保护 CI/CD 管道免受恶意软件包的攻击。这样可以确保在自动构建期间安装的任何软件包在安装前都会接受恶意软件检查。
## 为 CI/CD 安装
使用 `--ci` 标志即可自动为 CI/CD 环境配置 Aikido Safe Chain。这会在 PATH 中设置可执行 shim,而不是 shell 别名。
### Unix/Linux/macOS(GitHub Actions、Azure Pipelines 等)```shell
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh \
&& echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c - \
&& sh /tmp/install-safe-chain.sh --ci \
&& rm /tmp/install-safe-chain.sh
Windows(Azure Pipelines 等)```powershell
$installer = Join-Path $env:TEMP "install-safe-chain.ps1" Invoke-WebRequest "https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.ps1" -OutFile $installer -UseBasicParsing $expectedHash = "5FC22EEF74814BEF6828AA07C0EAEC79598F343F98B94A4ACAB823769AD56DA1" if ((Get-FileHash $installer -Algorithm SHA256).Hash -ne $expectedHash) { Remove-Item $installer -ErrorAction SilentlyContinue throw "Checksum verification failed for install-safe-chain.ps1" } & $installer -ci Remove-Item $installer
## 支持的平台
- ✅ **GitHub Actions**
- ✅ **Azure Pipelines**
- ✅ **CircleCI**
- ✅ **Jenkins**
- ✅ **Bitbucket Pipelines**
- ✅ **GitLab Pipelines**
## GitHub Actions 示例```yaml
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
- name: Install safe-chain
run: |
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh
echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c -
sh /tmp/install-safe-chain.sh --ci
rm /tmp/install-safe-chain.sh
- name: Install dependencies
run: npm ci
Azure DevOps 示例```yaml
-
task: NodeTool@0 inputs: versionSpec: "22.x" displayName: "Install Node.js"
-
script: | curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c - sh /tmp/install-safe-chain.sh --ci rm /tmp/install-safe-chain.sh displayName: "Install safe-chain"
-
script: npm ci displayName: "Install dependencies"
## CircleCI 示例```yaml
version: 2.1
jobs:
build:
docker:
- image: cimg/node:lts
steps:
- checkout
- run: |
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh
echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c -
sh /tmp/install-safe-chain.sh --ci
rm /tmp/install-safe-chain.sh
- run: npm ci
workflows:
build_and_test:
jobs:
- build
Jenkins 示例
注意:这假定 Jenkins 代理上已安装 Node.js 和 npm。```groovy pipeline { agent any
environment { // Jenkins does not automatically persist PATH updates from setup-ci, // so add the shims + binary directory explicitly for all stages. // If you installed into a custom directory, replace ~/.safe-chain with that path here. PATH = "${env.HOME}/.safe-chain/shims:${env.HOME}/.safe-chain/bin:${env.PATH}" }
stages { stage('Install safe-chain') { steps { sh ''' set -euo pipefail
# Install Safe Chain for CI
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh
echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c -
sh /tmp/install-safe-chain.sh --ci
rm /tmp/install-safe-chain.sh
'''
}
}
stage('Install project dependencies etc...') {
steps {
sh '''
set -euo pipefail
npm ci
'''
}
}
} }
## Bitbucket Pipelines 示例```yaml
image: node:22
steps:
- step:
name: Install
script:
- |
curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh
echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c -
sh /tmp/install-safe-chain.sh --ci
rm /tmp/install-safe-chain.sh
- export PATH=~/.safe-chain/shims:~/.safe-chain/bin:$PATH
- npm ci
After setup, all subsequent package manager commands in your CI pipeline will automatically be protected by Aikido Safe Chain's malware detection.
GitLab 流水线示例
要在 GitLab 流水线中添加 safe-chain,你需要将其安装到运行流水线的镜像中。可以通过以下方式完成:
-
定义一个 dockerfile 来运行你的构建 ```dockerfile FROM node:lts
Install safe-chain
RUN curl -fsSL https://github.com/AikidoSec/safe-chain/releases/download/1.5.15/install-safe-chain.sh -o /tmp/install-safe-chain.sh
&& echo "de0565e3d6346407a604e84e639e95fea8758748063da2216bbfdca5feda5dd2 /tmp/install-safe-chain.sh" | sha256sum -c -
&& sh /tmp/install-safe-chain.sh --ci
&& rm /tmp/install-safe-chain.shAdd safe-chain to PATH (update paths if you used a custom install dir)
ENV PATH="/root/.safe-chain/shims:/root/.safe-chain/bin:${PATH}"
-
在 CI 流水线中构建 Docker 镜像 ```yaml build-image: stage: build-image image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:latest . - docker push $CI_REGISTRY_IMAGE:latest
-
在流水线中使用镜像: ```yaml npm-ci: stage: install image: $CI_REGISTRY_IMAGE:latest script: - npm ci
此示例的完整流水线如下所示:```yaml stages:
- build-image
- install
build-image: stage: build-image image: docker:latest services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:latest . - docker push $CI_REGISTRY_IMAGE:latest
npm-ci: stage: install image: $CI_REGISTRY_IMAGE:latest script: - npm ci
# 故障排除
遇到问题?请参阅[故障排除指南](https://github.com/aikidosec/safe-chain/blob/HEAD/docs/troubleshooting.md)以获取常见问题的帮助。
# 报告问题
如果遇到问题:
1. 访问 [GitHub Issues](https://github.com/AikidoSec/safe-chain/issues)
2. 包括:
* 操作系统及版本
* Shell 类型及版本
* `safe-chain --version` 的输出
* 验证命令的输出
* 失败命令的详细日志(添加 `--safe-chain-logging=verbose` 参数)