perplexityai/bumblebee
GitHub: perplexityai/bumblebee
一个只读的开发者终端供应链清点工具,扫描磁盘上的包、扩展和工具元数据,用于检查已知供应链安全事件的本地暴露情况。
Stars: 4831 | Forks: 437
# bumblebee
Bumblebee 是一个只读的清点收集器,用于收集 macOS 和 Linux 开发者终端上的包、扩展以及开发者工具的元数据。
它解决了一个狭窄的供应链响应问题:当安全通告提及某个包、扩展或版本时,目前哪些开发机器的磁盘元数据中显示出匹配项?
SBOM 有助于回答发布了什么,EDR 有助于回答运行了什么或接触了什么网络,但供应链响应通常需要一个不同的视角:跨越 lockfile、包管理器元数据、扩展清单和支持的开发者工具配置中杂乱的本地状态。
Bumblebee 将这些分散的磁盘状态转换为结构化的 NDJSON 组件记录,并且在给定暴露目录时,当响应人员已经知道他们在寻找什么,它会标记出精确的匹配项,以便进行快速、只读的暴露检查。
## 范围
- 单个静态二进制文件,Go 1.25+,无非标准库依赖。
- 三种扫描配置(`baseline`、`project`、`deep`),适用于不同的群体和执行频率。
- 仅读取 [docs/inventory-sources.md](docs/inventory-sources.md) 中列出的 lockfile、包管理器安装元数据、扩展清单和支持的 MCP JSON 配置。不执行任何包管理器命令(`npm ls`、`pip show`、`go list` 等),也不读取源文件。MCP 主机配置可能在其 `env` 块中包含环境变量值和凭证;Bumblebee 会解析这些配置以获取所需的服务器清单,但不会在其输出的记录中包含这些值。
## 覆盖范围
| 家族 | 输出的 `ecosystem` | 来源 |
|---|---|---|
| npm | `npm` | `package-lock.json`, `npm-shrinkwrap.json`, `node_modules/.package-lock.json`, `node_modules//package.json` |
| pnpm | `npm` | `pnpm-lock.yaml`, `.pnpm/.../package.json` |
| Yarn | `npm` | `yarn.lock` (Classic + Berry) |
| Bun | `npm` | `bun.lock`; `bun.lockb` 存在性作为诊断 |
| PyPI | `pypi` | `*.dist-info/METADATA`, `INSTALLER`, `direct_url.json`, `*.egg-info/PKG-INFO` |
| Go modules | `go` | `go.sum`, `go.mod` |
| RubyGems | `rubygems` | `Gemfile.lock`, 已安装的 `*.gemspec` |
| Composer | `packagist` | `composer.lock`, `vendor/composer/installed.json` |
| MCP | `mcp` | JSON 主机配置:`mcp.json`, `.mcp.json`, `claude_desktop_config.json`, `mcp_config.json`, `mcp_settings.json`, `cline_mcp_settings.json`,外加 `~/.gemini/settings.json` (Gemini CLI / Code Assist) 和 `~/.claude.json` (Claude Code 用户和项目范围的 `mcpServers`)。非 JSON 配置(Codex `config.toml`,Continue YAML)在 v0.1 版本中不予解析。 |
| Agent skills | `agent-skill` | `skills.sh` / `vercel-labs/skills` lockfile:全局 `~/.agents/.skill-lock.json` (或 `$XDG_STATE_HOME/skills/.skill-lock.json`) 和本地项目的 `skills-lock.json`。没有 lockfile 的松散 `SKILL.md` 目录不予枚举。 |
| Editor extensions | `editor-extension` | VS Code, Cursor, Windsurf, VSCodium 清单 |
| Browser extensions | `browser-extension` | 每个 profile 的 Chromium 家族 (`manifest.json`) 和 Firefox (`extensions.json`) |
| Homebrew | `homebrew` | Formula `INSTALL_RECEIPT.json` 文件和 cask `.metadata` 安装标记 |
特定生态系统详情:[docs/inventory-sources.md](docs/inventory-sources.md)。
## 安装
需要 Go 1.25+。无非标准库依赖。
```
# 将最新的 tagged release 安装到 $GOBIN。
go install github.com/perplexityai/bumblebee/cmd/bumblebee@latest
# 或者 pin 特定的 tag。
go install github.com/perplexityai/bumblebee/cmd/bumblebee@v0.1.1
```
从检出的代码构建:
```
go build -o bumblebee ./cmd/bumblebee
go test ./...
```
在构建时打上显式版本号:
```
go build -ldflags "-X main.Version=v0.1.1" -o bumblebee ./cmd/bumblebee
```
`bumblebee version` 会打印版本号以及 VCS 修订版、构建时间和 Go 运行时——这样在生产环境中输出的记录就可以追溯到具体的构建版本。版本优先级:`-ldflags` 覆盖 > `go install` 记录的模块版本 > `VERSION` 中记录的树内默认值。
### 自测
安装后,对内置测试用例运行端到端检查:
```
bumblebee selftest
# selftest OK (1ms 内发现 2 个问题)
```
这些测试用例位于二进制文件内部,使用了故意伪造的包名(`bumblebee-selftest-evil@0.0.0`),并且不会进行任何网络调用。非零退出码意味着本地安装无法再检测到它本应检测到的内容——这是针对大规模推广部署的快速部署前冒烟测试。
## 配置
Bumblebee 是一个一次性扫描器:每次调用执行一次扫描然后退出。执行频率由运行者负责(cron, launchd, systemd, MDM 等)。每条记录都包含 `profile` 和针对根路径的 `root_kind`,以便接收方能够区分不同的群体。
| Profile | 扫描内容 | 用途 |
|---|---|---|
| `baseline` | 常见全局/用户包根目录、语言工具链、编辑器扩展、浏览器扩展和 MCP 配置。 | 通过外部运行器进行的周期性轻量级清点。 |
| `project` | 已配置的开发目录,例如 `~/code`、`~/src` 或 `~/work`。 | 针对已知项目工作区的周期性清点。 |
| `deep` | 显式 `--root` 路径,包括像 `$HOME` 这样的广泛根目录。 | 按需的事件或活动检查,通常配合 `--ecosystem`、`--exposure-catalog` 和 `--findings-only` 使用。 |
`baseline` 和 `project` 拒绝纯粹的家目录根路径;只有 `deep` 会遍历它们。
## 快速开始
```
# Baseline global inventory。
bumblebee scan --profile baseline > inventory.ndjson
# 使用显式 roots 进行每日 project sweep。
bumblebee scan --profile project \
--root "$HOME/code" \
--root "$HOME/Developer"
# 将运行限制在选定的 emitted ecosystems。
bumblebee scan --profile baseline \
--ecosystem npm,pypi \
--ecosystem go
# 针对已发布的 advisory 进行按需 exposure scan。
bumblebee scan --profile deep \
--root "$HOME" \
--exposure-catalog ./catalog.json \
--max-duration 10m
```
预览解析出的根目录而不进行扫描:
```
bumblebee roots --profile baseline
# 打印 "\t" 行
```
`--root` 是要扫描的文件系统路径;可重复使用,`deep` 模式必填,其他模式可选。`--ecosystem` 可重复使用并以逗号分隔。`--exposure-catalog` 接受 JSON 文件或包含 `*.json` 目录文件的目录(非递归合并,所有文件必须共享相同的 `schema_version`)。`--findings-only` 需要 `--exposure-catalog` 并抑制包记录,同时保留发现结果。`bumblebee scan --help` 列出了所有的 flag。
## 输出
记录是 NDJSON 格式,每行一条。诊断信息以 NDJSON 格式输出到 stderr。每次运行都以一条 `scan_summary` 记录结束;接收方使用它来决定是否将本次运行提升为当前状态。有关 HTTPS/文件输出,请参见 [docs/transport.md](docs/transport.md),有关接收方的当前状态模型,请参见 [docs/state-model.md](docs/state-model.md)。
包记录:
`confidence` (置信度):
- `high` — 精确的身份和版本来自规范的元数据。
- `medium` — 身份可靠,但版本或来源不完整。
- `low` — 仅包含配置/路径/规范引用;不能证明已安装的确切版本。
发现记录(匹配暴露目录):
`record_id` 是针对每种记录类型的规范身份元组的内容寻址哈希,在多次运行中保持稳定。各记录类型的字段列表和去重指南:[docs/state-model.md](docs/state-model.md#record-identity-record_id)。
## 暴露目录格式
精简的 JSON,仅进行精确的 `(ecosystem, name, version)` 匹配:
```
{
"schema_version": "0.1.0",
"entries": [
{
"id": "advisory-2026-0042",
"name": "example-pkg 1.2.3 (compromised release)",
"ecosystem": "npm",
"package": "example-pkg",
"versions": ["1.2.3"],
"severity": "critical"
}
]
}
```
目录必须是一个包含 `schema_version` 和 `entries` 键的 JSON 对象。拒绝纯粹的顶层数组。拒绝未来不受支持的 `schema_version` 值。通过将 `--exposure-catalog` 指向一个目录,可以同时加载多个目录文件;请参阅上面的 flag 描述。
### 示例暴露目录
[`threat_intel/`](threat_intel/) 目录存放着维护好的暴露目录,这些目录是根据公开的近期供应链活动的威胁情报报告构建的,并由 [Perplexity Computer](https://www.perplexity.ai/computer) 协助整理,随着新活动的报告通过 PR 进行更新。有关当前的目录列表和审查指南,请参见 [`threat_intel/README.md`](threat_intel/README.md)。
## 许可证
Apache License 2.0。参见 [LICENSE](LICENSE)。
示例包记录
``` { "record_type": "package", "record_id": "package:...", "schema_version": "0.1.0", "scanner_name": "bumblebee", "scanner_version": "v0.1.1", "run_id": "9b1f0c2e4d5a6b7c8d9e0f1a2b3c4d5e", "scan_time": "2026-05-15T18:22:01.482Z", "endpoint": { "hostname": "alex-mbp", "os": "darwin", "arch": "arm64", "username": "alex", "uid": "501", "device_id": "MDM-7F4A2B" }, "profile": "project", "ecosystem": "npm", "package_name": "@tanstack/query-core", "normalized_name": "@tanstack/query-core", "version": "5.59.20", "project_path": "/Users/alex/code/web-app", "root_kind": "project_root", "package_manager": "pnpm", "source_type": "pnpm-lockfile", "source_file": "/Users/alex/code/web-app/pnpm-lock.yaml", "has_lifecycle_scripts": false, "confidence": "high" } ```示例发现记录
``` { "record_type": "finding", "record_id": "finding:...", "schema_version": "0.1.0", "scanner_name": "bumblebee", "scanner_version": "v0.1.1", "run_id": "3a8c7d1e9f0b2a4c6d8e0f1a2b3c4d5e", "scan_time": "2026-05-15T18:22:01.482Z", "endpoint": { "hostname": "alex-mbp", "os": "darwin", "arch": "arm64", "username": "alex", "uid": "501", "device_id": "MDM-7F4A2B" }, "profile": "deep", "finding_type": "package_exposure", "severity": "critical", "catalog_id": "advisory-2026-0042", "catalog_name": "example-pkg 1.2.3 (compromised release)", "ecosystem": "npm", "package_name": "example-pkg", "normalized_name": "example-pkg", "version": "1.2.3", "root_kind": "deep_home_root", "project_path": "/Users/alex/code/web-app", "source_type": "pnpm-lockfile", "source_file": "/Users/alex/code/web-app/pnpm-lock.yaml", "confidence": "high", "evidence": "exact name+version match (version=1.2.3)" } ```标签:EVTX分析, Go, Homebrew安装, Ruby工具, 占用监测, 无线安全, 日志审计, 漏洞响应, 终端安全, 资产管理