prakhar0x01/sentryd
GitHub: prakhar0x01/sentryd
Sentryd 是一款 AI 辅助的软件供应链安全扫描器,专注于发现恶意包和 pipeline 攻击而非仅检测已知 CVE,并能自动生成蓝队检测规则。
Stars: 0 | Forks: 0
# 🛡️ Sentryd
**AI 辅助的软件供应链防御。**
Sentryd 旨在发现*恶意*包和 pipeline 漏洞 —— 而不仅仅是已知的 CVE ——
它用通俗易懂的英文解释每一项发现,并将检测规则交给您的蓝队,
以便在生产环境中捕获相同的攻击。
[功能](#features) · [架构](#architecture-overview) · [安装](#installation) ·
[快速开始](#quick-start) · [用法](#usage-guide) · [配置](#configuration) ·
[示例](#examples) · [工作原理](#how-it-works) · [常见问题](#faq) · [贡献](#contributing)
## 目录
- [什么是 Sentryd?](#what-is-sentryd)
- [诞生背景](#why-it-exists)
- [功能](#features)
- [架构概览](#architecture-overview)
- [安装说明](#installation)
- [快速开始](#quick-start)
- [使用指南](#usage-guide)
- [配置](#configuration)
- [示例](#examples)
- [工作原理](#how-it-works)
- [故障排除](#troubleshooting)
- [常见问题](#faq)
- [开发](#development)
- [项目结构](#project-structure)
- [安全考量](#security-considerations)
- [贡献](#contributing)
- [路线图](#roadmap)
- [许可证](#license)
- [鸣谢](#credits)
## 什么是 Sentryd?
Sentryd 是一个命令行**软件供应链扫描器**。您只需将它指向一个
代码仓库(或单个已发布的包),它就能回答大多数扫描器
无法回答的问题:
它分两个层级执行此操作:
1. 一个**低成本、确定性的静态层**,该层始终运行并查找可疑项
(域名抢注、安装钩子、依赖混淆、未锁定的依赖、
中毒的 CI workflow、已知漏洞)。
2. 一个**可选的 LLM 层**(`--deep`),它会获取被标记的包,安全地
解压它,仅将可疑片段发送给模型,并返回
可解释的行为判定。
然后,它将发现结果转化为安全团队实际使用的产出物:用于 GitHub 代码扫描的 **SARIF**、**SBOMs**(CycloneDX / SPDX),以及可直接部署的 **Sigma / KQL / Falco / YARA** 检测规则。
## 诞生背景
供应链安全中拥挤的领域是**已知漏洞** —— “您
依赖于存在 CVE-Y 的 lodash X。” 这是一个已经解决的大众化问题。
而尚未解决且极具价值的领域是**蓄意设计的恶意代码**,当它刚落地时
没有任何特征码:
- 一个包,在执行 `postinstall` 时,会窃取您的 npm/PyPI token 并将其
自身重新发布到您拥有的每一个包中(即 **Shai-Hulud** 蠕虫类别)。
- **依赖混淆** —— 一个公共包抢占了内部名称,而您的构建过程
会默默地优先选择它。
- **域名抢注 (Typosquats)** —— 携带 payload 的 `loadsh`、`reqeusts`、`python-dateutil` 克隆体。
- GitHub Actions 中的**中毒 pipeline 执行** —— 未锁定的 action 或
过度授权的 `GITHUB_TOKEN`,它将一个 pull request 变成了
在您的 CI runner 上执行的代码。
基于特征码的工具会漏掉这些,因为目前还没有特征码。要捕获它们
需要对**行为**进行推理 —— 这正是被强大的静态预过滤器限制住的 LLM 发挥作用的地方,同时扫描一个干净的代码仓库的成本依然约为 $0。
两项原则让 Sentryd 值得信赖:
- **从不执行不受信任的代码。** 分析是完全静态的 —— 获取、安全
解压、读取、推理。指向真正恶意的包也是安全的。
- **AI 是被限制的,而不是随意洒落的。** 静态层决定模型能看到什么,
从而控制成本,并且模型经过强化,能够抵御来自恶意
包源码的 prompt injection。
## 功能
| 领域 | 您将获得什么 |
|---|---|
| **生态系统** | npm(精确到 lockfile,包含传递依赖)、PyPI(`requirements.txt`)、Cargo(`Cargo.lock`)。支持插件化 —— 添加一个新生态仅需一个模块。 |
| **静态检测器** | 域名抢注、npm 安装钩子、未锁定的依赖、GitHub Actions 安全态势(未锁定的 actions、`write-all` token)。每一个都附带了真阳性**和**真阴性测试用例。 |
| **数据增强** | OSV.dev 已知漏洞查询、deps.dev 传递依赖解析、基于注册表的依赖混淆检测。带有缓存;在离线状态下可优雅降级。 |
| **LLM 行为层** | `--deep` 获取并安全解压包,对可疑文件进行分流,并通过 Anthropic API 返回结构化的 `{verdict, confidence, behaviors[], explanation, remediation}`。能够抵御 prompt injection。 |
| **可解释的发现** | 没有光秃秃的评分 —— 每一个发现都包含证据、解释和修复建议。 |
| **检测规则生成** | 经过验证的 **Sigma**(通过 pySigma)、**KQL**、**Falco** 和 **YARA**,根据发现的行为生成,带有 MITRE ATT&CK 标签和客观的误报提示。 |
| **策略即代码** | 在 `sentryd.policy.yaml` 中定义 `allow` / `deny` / `warn` 规则,在 CI 检查关口强制执行。 |
| **输出** | 丰富的终端表格、JSON、适配 GitHub 的 **SARIF**、独立的 **HTML 报告**,以及 **CycloneDX / SPDX SBOMs**。 |
| **易用性** | 已发布的 **GitHub Action**、**pre-commit hook**、`--fail-on` CI 检查关口,以及 `--notify`(Slack / webhook)。 |
| **红队测试面** | 被禁用的恶意包语料库、查准率/查全率**基准测试**,以及**规避测试套件** —— `sentryd redteam`。 |
| **注册表监控** | `sentryd watch` 扫描发布到 PyPI 的最新包,以发现可疑行为。 |
| **工程质量** | 严格类型检查(`mypy --strict`)、`ruff` lint + format、`pytest` 测试套件(单元 / 集成 / 语料库 / 可选的实时测试),以及自扫描(“吃自己的狗粮”)CI pipeline。 |
## 架构概览
Sentryd 是一个分层的 pipeline。每一层仅依赖于它下方的层;
`core` 包是所有人都会导入的共享底层基础。
```
┌──────────────────────────────────────────────┐
│ CLI │
│ scan · scan-package · ci · sbom · rules · │
│ watch · redteam │
└───────────────────────┬────────────────────────┘
│
┌───────────┐ ┌───────────┐ ┌──────▼──────────────┐ ┌──────────────┐
│ INGEST │───▶│ ENRICH │───▶│ ANALYSIS │───▶│ OUTPUT │
│ npm/pypi/ │ │ OSV │ │ static tier (always)│ │ table · json │
│ cargo │ │ deps.dev │ │ LLM tier (--deep) │ │ SARIF · HTML │
│ + fetch │ │ registry │ │ correlate + policy │ │ SBOM · rules │
└───────────┘ └───────────┘ └─────────────────────┘ └──────────────┘
│
cross-cutting: SANDBOX (no-exec extract) · CACHE ·
CONFIG · LOGGING · PLUGIN REGISTRY
```
### 数据流
1. **摄取** 将项目目录转化为 `DependencyGraph`(如果存在
lockfile,则从中解析出版本)。纯静态读取 —— 绝不执行安装钩子。
2. **增强**(网络相关,可选)添加 OSV 已知漏洞发现结果,当没有 lockfile 时通过 deps.dev 扩展传递图,并通过注册表中名称的存在性来检查依赖混淆。
3. **静态分析** 针对该图运行声明式检测器(数据位于 `detectors/*.yaml` 中)。确定性执行且始终开启。
4. **LLM 分析**(`--deep`)仅针对被标记的包运行,且仅针对相关的切片:获取 -> 安全解压 -> 选择可疑文件 -> 模型 -> 结构化判定。
5. **关联** 合并静态和 LLM 信号,进行去重、评分,并应用 **策略**(allow/deny/warn)。
6. **输出** 呈现结果(表格 / JSON / SARIF / HTML / SBOM),并且可以
根据行为生成检测规则。
### 设计决策
- **检测器是数据,而不是代码。** 一项新检查就是一个 YAML 定义加上一个
可复用的评估器 —— 保持贡献摩擦力低且引擎整洁。
- **两层分流控制成本。** 昂贵的模型只能看到免费层
标记的内容,并且仅仅是其相关的切片。
- **所有结构化的内容都是 Pydantic 模型**(`core/models.py`)—— 子系统之间的
契约。人类可读的输出使用 Rich;机器输出在 stdout 上是纯净的字节流,因此可以通过管道完美传输。
## 安装说明
### 前置条件
| 需求 | 说明 |
|---|---|
| **Python 3.12+** | CI 环境已测试 3.12 和 3.13 版本。 |
| **[uv](https://docs.astral.sh/uv/)** | 推荐的安装器/运行器。它会自动配置合适的 Python。 |
| 网络(可选) | 增强功能(`OSV`、`deps.dev`)、`--deep`、`scan-package` 和 `watch` 所需。其他所有功能均可离线工作。 |
| `ANTHROPIC_API_KEY`(可选) | 仅在 `--deep` LLM 层必需。如果没有它,Sentryd 将以纯静态模式运行。 |
### 支持的操作系统
支持 Linux、macOS 和 Windows(纯 Python 实现,无原生构建步骤)。
### 安装 `uv`
**macOS / Linux:**
```
curl -LsSf https://astral.sh/uv/install.sh | sh
```
(macOS 用户也可以执行 `brew install uv`。)
**Windows (PowerShell):**
```
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```
### 从源码安装 Sentryd
```
git clone https://github.com/prakhar0x01/sentryd
cd sentryd
uv sync # creates .venv and installs everything
uv run sentryd --help # verify
```
`uv run sentryd ...` 会在受管环境中运行 CLI。要在您的 `PATH` 中获得直接的
`sentryd` 命令,请将该项目作为工具安装:
```
uv tool install .
sentryd --help
```
## 快速开始
```
# 1. 扫描仓库(静态,支持离线)
uv run sentryd scan ./your-repo
# 2. 添加深度行为分析(需要 API key)
export ANTHROPIC_API_KEY=sk-ant-...
uv run sentryd scan ./your-repo --deep
# 3. 分析单个已发布的 package
uv run sentryd scan-package express@4.18.2
# 4. 用作 CI 门禁(发现 high+ 级别的问题以非零状态退出,并输出 SARIF)
uv run sentryd ci ./your-repo --fail-on high > results.sarif
# 5. 从上次扫描中生成蓝队检测规则
uv run sentryd rules --from last-scan --format all --output ./rules
```
## 使用指南
### 命令
| 命令 | 用途 |
|---|---|
| `sentryd scan
` | 扫描项目:依赖项、lockfile 和 CI 配置。 |
| `sentryd scan-package ` | 获取并分析单个已发布的包,例如 `express@4.18.2`。 |
| `sentryd ci ` | CI 检查关口模式:生成机器可读的产出物(默认为 SARIF),并在发生策略/严重性违规时以非零状态退出。 |
| `sentryd sbom ` | 生成 CycloneDX 或 SPDX 的软件物料清单 (SBOM)。 |
| `sentryd rules --from last-scan` | 根据上次扫描的发现结果输出经过验证的 Sigma/KQL/Falco/YARA 规则。 |
| `sentryd watch [pypi]` | 扫描发布到注册表的最新包,以发现可疑行为。 |
| `sentryd redteam --suite all` | 运行语料库基准测试和规避测试套件。 |
| `sentryd --version` | 打印版本信息。 |
运行任何带有 `--help` 的命令以查看其完整选项。
### 典型工作流:扫描代码仓库
```
# 静态扫描(快速,除了 OSV enrichment 外无需网络)
uv run sentryd scan ./my-app
# 完全离线(跳过 OSV / deps.dev / registry 查找)
uv run sentryd scan ./my-app --no-enrich
# 对标记的 packages 进行深度行为分析
uv run sentryd scan ./my-app --deep --fail-on high
# 用于工具的机器输出
uv run sentryd scan ./my-app --output json > scan.json
uv run sentryd scan ./my-app --output sarif > scan.sarif
uv run sentryd scan ./my-app --output html > report.html
```
### 进阶用法
```
# 执行组织策略(allow/deny/warn)
uv run sentryd scan ./my-app --policy sentryd.policy.yaml
# 通过 scan summary 通知 Slack / 通用 webhook
uv run sentryd scan ./my-app --notify "$SLACK_WEBHOOK_URL"
# 仅生成 Sigma 规则到目录中
uv run sentryd rules --format sigma --output ./detections
# 使用 LLM tier 监控 50 个最新的 PyPI packages
uv run sentryd watch pypi --limit 50 --deep
```
### 在 CI 中 (GitHub Action)
发现结果会通过 SARIF 在 GitHub 的 **Security** 标签页中原生呈现:
```
# .github/workflows/supplychain.yml
name: supply-chain
on: [push, pull_request]
permissions:
contents: read
security-events: write # required to upload SARIF to code scanning
jobs:
sentryd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: prakhar0x01/sentryd@v1
with:
path: .
fail-on: high
```
### 作为 pre-commit hook
```
# .pre-commit-config.yaml
repos:
- repo: https://github.com/prakhar0x01/sentryd
rev: v0.1.0
hooks:
- id: sentryd
```
## 配置
配置将从以下来源解析,**后者会覆盖前者**:
1. 内置默认值。
2. 被扫描目录中的 `sentryd.yaml`。
3. `~/.config/sentryd/config.yaml`(用户级别)。
4. 通过 `--config` 传递的文件。
5. 环境变量。
6. CLI 标志。
### 配置文件 (`sentryd.yaml`)
复制 [`sentryd.yaml.example`](./sentryd.yaml.example):
```
api_key: "" # prefer the ANTHROPIC_API_KEY env var
fail_on: high # info | low | medium | high | critical
deep: false # enable the LLM tier (auto-disabled without a key)
enrich: true # OSV / deps.dev / registry lookups (false = offline)
ecosystems: [npm, pypi]
output: json # json | sarif | html
cache_dir: ~/.cache/sentryd
log_level: warning # debug | info | warning | error
# policy_file: sentryd.policy.yaml
```
### 环境变量
| 变量 | 用途 |
|---|---|
| `ANTHROPIC_API_KEY` | 用于 `--deep` LLM 层的 API key。 |
| `SENTRYD_FAIL_ON` | 触发失败的最低严重性。 |
| `SENTRYD_DEEP` | `true`/`false` —— 启用 LLM 层。 |
| `SENTRYD_ENRICH` | `true`/`false` —— 启用网络数据增强。 |
| `SENTRYD_OUTPUT` | 默认输出格式。 |
| `SENTRYD_ECOSYSTEMS` | 逗号分隔的生态系统,例如 `npm,pypi`。 |
| `SENTRYD_CACHE_DIR` | 缓存目录。 |
| `SENTRYD_LOG_LEVEL` | 日志记录级别。 |
| `LOG_FORMAT` | 设置为 `json` 以在 CI 中输出结构化日志。 |
关键标志
| 标志 | 命令 | 默认值 | 含义 |
|---|---|---|---|
| `--deep` | `scan`, `scan-package`, `watch` | 关闭 | 启用 LLM 行为层。 |
| `--fail-on` | `scan`, `ci` | `high` | 决定以非零状态退出的最低严重性。 |
| `--output` | `scan`, `scan-package`, `ci` | table / sarif | `json` \| `sarif` \| `html`。 |
| `--no-enrich` | `scan` | 关闭 | 跳过网络增强(完全离线)。 |
| `--policy` | `scan`, `ci` | 无 | 指向 `sentryd.policy.yaml` 的路径。 |
| `--notify` | `scan`, `ci` | 无 | 用于 POST 扫描摘要的 Webhook/Slack URL。 |
| `--format` | `sbom`, `rules` | — | SBOM / 规则格式选择器。 |
### 策略即代码 (`sentryd.policy.yaml`)
```
version: "1"
rules:
- action: deny # fail the build on this finding, any severity
rule_id: typosquat-popular
reason: "No typosquats permitted in production builds"
- action: warn # report but never fail
severity_min: medium
reason: "Surface medium+ findings for review"
- action: allow # suppress an approved exception
package_name: internal-auth-sdk
reason: "Approved internal package"
```
规则从上到下求值;匹配的第一条规则生效。
## 示例
### 1. 域名抢注检测
**输入** —— 一个依赖于 `loadsh`(`lodash` 的域名抢注)的 `package.json`。
**命令:**
```
uv run sentryd scan ./my-app
```
**输出:**
```
╭──────────────── Sentryd ─────────────────╮
│ Scanning ./my-app... │
╰──────────────────────────────────────────╯
Findings
┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Severity ┃ Conf. ┃ Rule ┃ Package ┃ Explanation ┃
┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━┩
│ high │ medium │ typosquat-popular │ loadsh@1.0.0 │ Dependency 'loadsh' │
│ │ │ │ │ is within edit │
│ │ │ │ │ distance 1 of the │
│ │ │ │ │ popular package │
│ │ │ │ │ 'lodash'. │
└──────────┴────────┴───────────────────┴──────────────┴───────────────────────┘
1 findings in 1 package(s) · static only · 0.003s
```
### 2. 用于工具对接的 JSON 输出
**命令:**
```
uv run sentryd scan ./my-app --output json
```
**输出(经裁剪):**
```
{
"scanned_path": "./my-app",
"packages_scanned": 1,
"llm_tier_used": false,
"findings": [
{ "rule_id": "npm-install-hook", "severity": "medium", "package": "my-app@0.0.1" },
{ "rule_id": "unpinned-dependency", "severity": "low", "package": "left-pad@^1.3.0" }
]
}
```
### 3. 生成检测规则
**命令:**
```
uv run sentryd scan ./my-app # produces the last scan
uv run sentryd rules --from last-scan --format sigma
```
**输出(一条生成的、通过 pySigma 验证的规则):**
```
title: Package manager install hook spawns a child process
id: 3c2303a6-460d-49bb-8b02-5f2f5b2d5762
status: experimental
logsource:
category: process_creation
product: linux
detection:
selection:
ParentImage|endswith: ['/npm', '/yarn', '/pnpm', '/pip', '/node']
CommandLine|contains: ['postinstall', 'preinstall', 'sh -c', 'curl', 'wget']
condition: selection
level: medium
tags:
- attack.t1195.002
falsepositives:
- Native modules with legitimate build steps (node-gyp, prebuild)
```
### 4. 红队基准测试 + 规避套件
**命令:**
```
uv run sentryd redteam --suite all
```
**输出:**
```
Corpus benchmark (static tier)
┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Entry ┃ Expected ┃ Detected ┃ Outcome ┃ Detectors ┃
┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ ci-poisoned-pipeline │ malicious │ yes │ TP │ gha-broad-permissio… │
│ npm-clean-lib │ benign │ no │ TN │ - │
│ npm-install-stealer │ malicious │ yes │ TP │ npm-install-hook │
│ npm-scoped-private │ benign │ no │ TN │ - │
│ npm-typosquat-loadsh │ malicious │ yes │ TP │ typosquat-popular │
└──────────────────────┴───────────┴──────────┴─────────┴──────────────────────┘
precision=1.00 recall=1.00 f1=1.00 (tp=3 fp=0 fn=0 tn=2)
Evasion suite (vs static tier)
... baseline / preinstall-hook / prepare-hook / external-file /
obfuscated-command → caught ; runtime-only → BYPASS
1/6 variant(s) bypassed the static tier — each is a documented gap handled by the LLM tier.
```
### 5. 包的深度行为分析
**命令:**
```
export ANTHROPIC_API_KEY=sk-ant-...
uv run sentryd scan-package some-suspicious-pkg@1.0.0 --deep --output json
```
**输出(结构):**
```
{
"findings": [{
"rule_id": "llm-behavioral",
"name": "LLM behavioral verdict: malicious",
"severity": "critical",
"llm_verdict": {
"verdict": "malicious",
"confidence": 0.95,
"self_propagation": false,
"behaviors": [{
"behavior": "credential-exfiltration",
"evidence": "postinstall reads ~/.npmrc and POSTs it to http:///c",
"location": "scripts/postinstall.js:12-19"
}],
"explanation": "The install hook reads the npm auth token and sends it to a remote host.",
"remediation": "Do not install this package; rotate any exposed npm tokens."
}
}]
}
```
## 工作原理
首次扫描的引导式演练。
1. **您运行扫描。**
uv run sentryd scan ./my-app --fail-on high
2. **Sentryd 检测生态系统并构建依赖图。** 它会找到
`package.json`(如果存在还有 lockfile)并解析出确切、完整的传递
包集合 —— 仅读取字节,绝不执行任何内容。
3. **运行增强(如果在线)。** 每个确切版本的包都会与
OSV.dev 进行比对,以检查已知漏洞;直接依赖项会被检查是否存在
依赖混淆(即在公共注册表中无法声明的名称)。在此期间,您会看到
`Scanning ./my-app...` 面板。
4. **静态层评估每个检测器。** 域名抢注、安装钩子、
未锁定的依赖项以及 CI 安全态势问题会作为发现结果呈现 —— 每一项
都附带证据和修复建议。
5. **(可选)深度层分析被标记的包。** 结合 `--deep` 和 API
key,Sentryd 会获取每个被标记的包,安全地将其解压,仅选择
可疑文件,并向模型请求结构化的行为判定。
6. **您将看到结果**,以按严重性着色的表格形式呈现(最严重的在最上面),以及一行摘要,
例如 `2 findings in 37 package(s) · static only · 0.4s`。
7. **检查关口决定退出代码。** 如果任何发现结果达到或超过 `--fail-on`
(或匹配了策略 `deny`),Sentryd 将以非零状态退出 —— 从而使您的 CI 失败。
8. **接下来您可以。** 为 SOC 生成检测规则
(`sentryd rules --from last-scan`),在 GitHub 的 Security 标签页中打开 SARIF,或者
为已审查确认的误报添加 `allow` 策略规则。
## 故障排除
| 症状 | 原因 | 解决方法 |
|---|---|---|
| `LLM tier: no API key set, skipping.` | 在没有 `ANTHROPIC_API_KEY` 的情况下使用了 `--deep`。 | `export ANTHROPIC_API_KEY=sk-ant-...`,或者去掉 `--deep`。 |
| 扫描卡住或运行缓慢 | 在大型依赖图或慢速网络连接上进行网络增强(OSV/deps.dev)。 | 添加 `--no-enrich` 进行快速的离线扫描。 |
| `Invalid value for 'PATH': ... does not exist` | 扫描路径错误。 | 传入一个存在的路径;对于单个包,请使用 `scan-package`。 |
| `sentryd rules` 提示 “No previous scan found” | 尚未运行过任何扫描(规则读取的是上一次扫描结果)。 | 先运行 `sentryd scan `。 |
| `watch npm ...` 被拒绝 | 目前只有 PyPI 支持最新包的数据流。 | 请使用 `sentryd watch pypi`。 |
| 在您自己代码仓库的 CI 上发现结果 | Sentryd 标记了未锁定的 GitHub Actions / `write-all` token。 | 将 actions 锁定到 commit SHA 并限制 `permissions:` 范围,或者添加 `allow`/`warn` 策略规则。 |
| Security 标签页中没有 SARIF | 缺少 `security-events: write` 权限。 | 将其添加到 workflow 的 `permissions:` 块中。 |
要进行调试,请提高日志级别:
```
SENTRYD_LOG_LEVEL=debug uv run sentryd scan ./my-app # human logs on stderr
LOG_FORMAT=json SENTRYD_LOG_LEVEL=info uv run sentryd scan ./my-app # structured
```
## 常见问题
**Sentryd 会执行它扫描的包吗?**
不,绝对不会。分析是完全静态的 —— 它获取 tarball,使用
经过强化且禁止执行的解压器解压它们,然后读取字节。安装钩子、`setup.py` 以及
类似的东西永远不会被运行。这也是为什么将其指向恶意包是安全的。
**我需要 API key 吗?**
仅在 `--deep` LLM 层需要。其他所有功能 —— 静态检测器、OSV
增强、SARIF/SBOM、检测规则 —— 没有它也能正常工作。
**深度层的成本是多少?**
一个干净的代码仓库成本约为 $0,因为没有任何内容会发送到模型。只有静态
层标记的包才会被分析,并且仅发送相关的切片区域。判定结果
会被缓存,因此重新扫描相同的版本是免费的。
**支持哪些生态系统?**
目前支持 npm、PyPI 和 Cargo。插件架构使得添加 Go、Maven 或
RubyGems 仅需单个模块。
**它准确吗?**
静态层已针对禁用的恶意包语料库
(`sentryd redteam --suite benchmark`)进行了基准测试,并为
每个检测器提供了真阳性和真阴性测试用例。我们将误报视为比
漏报更严重的问题。
**我可以完全离线运行它吗?**
可以:`sentryd scan --no-enrich` 会跳过所有的网络调用。
**为什么我自己的代码仓库会被标记?**
如果您的 CI workflow 使用了未锁定的 actions 或 `write-all` token,Sentryd 就会
报告它 —— 这是一个真实的安全态势发现。请将其锁定到 SHA、限制权限范围,或者通过策略允许它。
## 开发
```
git clone https://github.com/prakhar0x01/sentryd
cd sentryd
uv sync
```
### 质量检查关口(每次提交前运行)
```
uv run ruff check . # lint
uv run ruff format --check . # formatting
uv run mypy src/ # strict type checking
uv run pytest -q # full test suite
```
或者一次性全部运行:
```
uv run ruff check . && uv run ruff format . && uv run mypy src/ && uv run pytest -q
```
### 测试套件
```
uv run pytest -q # everything (live tests auto-skip)
uv run pytest -m corpus # malicious-package zoo regression
RUN_LIVE=1 uv run pytest -m live # opt-in tests that hit the real Anthropic API (cost money)
```
该套件包含 32 个测试模块,覆盖了单元测试、集成测试、端到端测试(通过 Typer 的
`CliRunner`)以及语料库回归测试。网络代码使用
`pytest-httpx` 进行 mock;LLM 分析器则使用注入的 fake client 进行测试。
### 调试
- `SENTRYD_LOG_LEVEL=debug` 会在 stderr 上输出 pipeline 日志。
- `LOG_FORMAT=json` 输出供机器消费的结构化日志。
- 机器可读的输出(`--output json|sarif`)在 stdout 上是纯净的字节流;状态/日志会输出到
stderr,因此 `sentryd ci . | jq` 可以正常工作。
请参阅 [CONTRIBUTING.md](./CONTRIBUTING.md) 获取完整的贡献指南,包括
如何添加检测器。
## 项目结构
```
sentryd/
├── src/sentryd/
│ ├── cli.py # Typer entrypoint and command wiring (composition root)
│ ├── core/ # models, config, cache, logging, console, plugin registry
│ ├── ingest/ # npm / pypi / cargo parsers + tarball fetch
│ ├── enrich/ # OSV, deps.dev, registry metadata clients
│ ├── analysis/
│ │ ├── static/ # detector engine + evaluators (typosquat, install-hook, …)
│ │ ├── llm/ # triage, file selection, prompts, analyzer, deep orchestration
│ │ ├── correlate.py # merge + dedupe + score findings
│ │ └── policy.py # allow/deny/warn evaluation
│ ├── rules/ # Sigma/KQL/Falco/YARA generation + validation
│ ├── output/ # sarif, html, sbom, json, notifiers
│ ├── monitor/ # registry feed watcher (`watch`)
│ ├── redteam/ # corpus loader, benchmark, evasion suite
│ └── sandbox/ # hardened, no-execution archive extraction
├── detectors/ # declarative detector definitions (YAML)
├── rule_templates/ # Sigma/KQL/Falco/YARA Jinja templates
├── corpus/ # defanged malicious-package zoo + manifests
├── tests/ # pytest suite + fixtures
├── docs/ # MkDocs documentation site
├── action.yml # published GitHub Action
├── .pre-commit-hooks.yaml # pre-commit hook provider
├── sentryd.yaml.example # sample config
└── sentryd.policy.yaml.example
```
## 安全考量
Sentryd 旨在被指向真正恶意的代码。它的安全
保证、威胁模型和已知限制均记录在
[SECURITY.md](./SECURITY.md) 中。简而言之:
- 不受信任的代码**绝不执行**;解压经过强化(防止路径遍历、
符号链接和压缩炸弹攻击)。
- LLM 层将包源码视为恶意输入,并从
结构化字段中读取其判定(抵御 prompt injection)。
- 网络出口流量采用白名单制(注册表 / OSV / deps.dev / Anthropic),外加
明确选择启用的 `--notify` webhook。
- 密钥从环境中读取,绝不记录在日志中。
如需报告漏洞,请参阅 [SECURITY.md](./SECURITY.md#reporting-a-vulnerability)。
## 贡献
欢迎您的贡献!请阅读 [CONTRIBUTING.md](./CONTRIBUTING.md) 了解
开发环境设置、质量标准、不可妥协的安全规则,以及如何添加
检测器。
简而言之:从 `main` 分支切出,使用 [约定式提交 (Conventional Commits)](https://www.conventionalcommits.org/),
保持所有四个质量检查关口全部通过,并为任何
新增的检测同时添加真阳性和真阴性测试。
## 路线图
已实现并发布:npm/PyPI/Cargo 摄取、OSV/deps.dev/registry 增强、
静态检测器层、LLM 深度层、检测规则生成、
策略即代码、SARIF/SBOM/HTML 输出、GitHub Action + pre-commit hook、
红队语料库/基准测试/规避套件,以及 PyPI 注册表监控。
计划中:
- 更多生态系统(Go modules、Maven、RubyGems),通过现有的插件模式实现。
- npm 注册表监控(复制流水线)。
- 可达性分析 —— 确认危险代码路径是否被实际触发。
- 针对语料库的规则查准率/查全率评分。
- PDF 报告和额外的通知接收器。
## 许可证
在 [MIT 许可证](./LICENSE) 下发布。
## 鸣谢
由 **[prakhar0x01](https://github.com/prakhar0x01)** 创建并维护。标签:DLL 劫持, IP 地址批量处理, LLM防护, 云安全监控, 域名收集, 大语言模型, 恶意包检测, 文档安全, 软件供应链安全, 远程方法调用, 逆向工具, 配置审计, 静态分析