Crawl4AI SBOM 深度解析:CycloneDX 依赖清单的结构、内容与再生成流程
Crawl4AI 仓库在 sbom/ 目录下维护了一份 CycloneDX 格式的软件物料清单(Software Bill of Materials, SBOM),用于完整披露项目运行时依赖的组件、许可证与版本。本文以 sbom/README.md 和 sbom/sbom.cdx.json 为主体,结合生成脚本 scripts/gen-sbom.sh 的源码,讲解这份 SBOM 的规范版本、组件构成、依赖图谱结构,以及如何在本地验证与再生成它。
一、SBOM 在 Crawl4AI 中的定位与官方声明
sbom/ 目录是 Crawl4AI 仓库中存放合规与供应链透明度资产的位置,目录内仅包含两个文件:
- sbom/README.md:说明该目录用途、免责声明以及再生成方式;
- sbom/sbom.cdx.json:实际的 CycloneDX JSON 清单文件(约 1 MB)。
sbom/README.md 中的声明是理解这份文件边界的关键:
- 用途声明:该目录包含项目的 CycloneDX SBOM;
- 免责条款(Disclaimer):该 SBOM 是基于项目元数据“尽力而为”(best-effort)生成的,反映的是生成时刻的依赖状态,不构成完整性或准确性的保证;
- 再生成方式:通过运行
./scripts/gen-sbom.sh重新生成。
这一免责声明很重要:Crawl4AI 是一个依赖面很广的 Web 爬虫框架(Playwright、aiohttp、Pydantic 等),其实际环境还包含 uv.lock 锁定的开发依赖、.venv 中已安装的包以及 Docker 部署镜像的依赖。SBOM 捕获的是“某一次构建/扫描时点”的快照,因此使用者在将其用于安全审计或合规申报时,应当以仓库最新一次再生成的结果为准,而不是直接引用历史快照。
二、SBOM 的规范版本与元数据
从 sbom/sbom.cdx.json 的顶层字段可以确认其格式与生成工具信息:
| 字段 | 值 | 含义 |
|---|---|---|
bomFormat |
CycloneDX |
采用 CycloneDX 标准 |
specVersion |
1.6 |
CycloneDX 规范 1.6 版本 |
serialNumber |
urn:uuid:03585831-4a90-4206-8589-7c4d89f6d58c |
SBOM 文档的唯一序列号(URN UUID),便于下游工具去重与引用 |
version |
1 |
文档版本号 |
metadata.timestamp |
2026-01-27T01:43:08Z |
生成时间戳 |
metadata.tools.components |
syft v1.40.1(author: anchore) |
实际执行扫描的引擎 |
metadata.component |
type: file, name: "." |
被扫描的根组件即仓库根目录本身 |
其中 metadata.tools 字段明确记录了本次清单由 anchore 出品的 syft 1.40.1 生成——这与下文生成脚本中调用的工具一致。metadata.component 声明根组件为 .(项目根目录),说明 syft 是对整个仓库目录树(而非单一构建产物)做的文件级与包级联合扫描。
三、组件构成:679 个组件如何分类
顶层 components 数组共包含 679 个组件,按 type 字段可分为三类:
| 组件类型 | 数量 | 说明 |
|---|---|---|
library |
278 | 软件库,绝大多数为 PyPI 包(purl 形如 pkg:pypi/aiohttp@3.13.3),也包含 GitHub Actions(如 pkg:github/actions/checkout@v4) |
file |
385 | 仓库内的文本文件(如工作流、脚本、文档),每个条目携带 SHA-1 与 SHA-256 双哈希 |
application |
16 | 被识别为“应用/二进制”的组件,例如 Python 虚拟环境中随包分发的 PE 可执行文件(pip 的 distlib 启动器、setuptools 的 cli 二进制等) |
几个值得注意的实际样本(均可在 sbom/sbom.cdx.json 中检索到):
1. 项目自身作为一个组件被收录。 清单中存在 purl: pkg:pypi/crawl4ai@0.7.8 的 library 组件,带有作者 Unclecode、许可证 Apache-2.0 以及推导出的 CPE(cpe:2.3:a:unclecode_...:python-crawl4ai:0.7.8:...)。这说明扫描器从已安装的 crawl4ai 包元数据中识别出了项目本体。需要留意的是:该组件版本(0.7.8)对应生成时点的环境,而当前仓库 crawl4ai/version.py 中 __version__ 已演进为 0.9.0,这也印证了 README 中“快照仅反映生成时刻依赖”的免责声明。
2. 许可证信息并非全量。 679 个组件中只有 126 个携带 licenses 字段。syft 依赖包元数据(dist-info/METADATA)与 lock 文件中的许可证声明,未声明的组件不会虚构许可证值——使用时应按“缺省即未知”处理。
3. 同一包可能出现多个版本。 例如 aiohttp 同时存在 3.12.13(来自 /uv.lock)与 3.13.3(来自 .venv 的 dist-info),click 存在 8.1.8 与 8.3.1,certifi 存在 2025.7.9 与 2026.1.4。这不是数据错误,而是扫描范围覆盖了“锁定声明”与“实际安装”两个层面(见下一节)。
四、依赖图谱与来源溯源(properties 属性)
CycloneDX 1.6 的 dependencies 数组在 sbom/sbom.cdx.json 中共有 140 个条目,每个条目以组件 bom-ref 为键、dependsOn 为值,构成依赖关系图。例如:
{
"ref": "pkg:pypi/aiohttp@3.13.3?package-id=0eeb93580cf1583c",
"dependsOn": ["pkg:pypi/aiosignal@1.4.0?..."]
}
从结构看,这些关系主要由 uv.lock 中的锁定元数据推导而来,可以直接用于下游 SBOM 工具做依赖链分析(如“某个漏洞组件被哪条链引入”)。
每个组件还携带 properties 数组,其中 syft 的溯源属性是审计的关键:
syft:package:foundBy:发现该组件的 cataloger(扫描器),如github-actions-usage-cataloger、pe-binary-package-cataloger等;syft:package:type:包的分类,取值包括python(PyPI 包)、github-action(GitHub Actions)、binary(二进制)等;syft:location:0:path等:组件在仓库中的物理位置,这是最实用的溯源字段。
按位置前缀统计所有组件的出处,可以清楚看出 syft 实际扫描了哪些来源:
| 来源路径 | 组件命中次数 | 对应仓库文件 |
|---|---|---|
/uv.lock |
127 | uv.lock(项目锁文件,声明层依赖) |
/.venv/... |
378 | 生成时点的 Python 虚拟环境(安装层依赖,含 dist-info 元数据) |
/.github/workflows/... |
8 | CI 工作流(如 .github/workflows/main.yml 中引用的 Ilshidur/action-discord、.github/workflows/release.yml 中的 actions/checkout@v4、actions/setup-python@v5) |
/deploy/docker/requirements.txt |
6 | deploy/docker/requirements.txt(Docker 服务端部署的 Python 依赖) |
其他(根目录 requirements.txt 等) |
2 | requirements.txt 等 |
也就是说,这份 SBOM 实际上把 Crawl4AI 的四条依赖面都纳入了视野:开发/锁定的主依赖(uv.lock + pyproject.toml)、实际运行环境(.venv)、Docker 部署镜像(deploy/docker/ 的 requirements 与服务代码 deploy/docker/server.py)、以及 CI 供应链(GitHub Actions)。对于评估一个爬虫框架的攻击面——第三方 Action、HTTP 客户端、证书库(如 certifi、cryptography)——这份清单提供了逐条可查的证据。
五、再生成 SBOM:gen-sbom.sh 脚本剖析
sbom/README.md 给出的再生成命令背后,是 scripts/gen-sbom.sh 这个 15 行的小脚本,其完整逻辑如下:
#!/usr/bin/env bash
set -euo pipefail
# Generate CycloneDX JSON SBOM using Syft
# Output: sbom.cdx.json in project root
cd "$(dirname "$0")/.."
if ! command -v syft &> /dev/null; then
echo "Error: syft is not installed. Install from https://github.com/anchore/syft" >&2
exit 1
fi
syft . -o cyclonedx-json=sbom/sbom.cdx.json
echo "SBOM generated: sbom/sbom.cdx.json"
逐行理解几个关键设计:
set -euo pipefail:严格错误模式,任一命令失败即终止,避免生成出残缺的清单;cd "$(dirname "$0")/..":无论调用方位于哪个目录,都先切换到脚本上一级(即仓库根目录),保证syft .的扫描根是项目根;- 前置检查
command -v syft:syft 未安装时直接报错退出(脚本注释中指明了 syft 的安装来源,为 anchore 官方项目),而不是让syft命令静默失败; - 核心扫描命令
syft . -o cyclonedx-json=sbom/sbom.cdx.json:对当前目录树执行全量 catalog,输出 CycloneDX JSON 并直接写入 sbom/sbom.cdx.json。
因此复现流程为:
# 1. 安装 syft(anchore 官方工具),例如通过包管理器或官方安装脚本
# 2. 在仓库根目录执行:
./scripts/gen-sbom.sh
# 输出:SBOM generated: sbom/sbom.cdx.json
需要注意两个适用前提:其一,扫描结果与执行环境强相关——若在干净的 checkout 中运行(无 .venv),生成的清单将不含安装层组件,主要反映 uv.lock、requirements.txt 与 CI 工作流的声明依赖;其二,生成产物直接覆盖仓库内文件,应通过版本控制 diff 审阅变更,而不是盲目信任单次输出。这与 sbom/README.md 的 best-effort 免责声明一脉相承。
六、如何阅读与利用这份 SBOM(实用建议)
面向供应链安全、合规审计或依赖治理场景,结合本仓库的实际结构,给出几条可操作的用法:
- 验证文件完整性:
file类组件携带 SHA-256 哈希,可用于比对 CI 工作流等关键文件是否在传输中被篡改; - 版本漂移检查:对比
metadata.component中crawl4ai的版本与 crawl4ai/version.py、pyproject.toml(通过attr = "crawl4ai.__version__.__version__"动态取版本)中的当前版本,可判断清单是否过期;本仓库快照中的0.7.8与当前0.9.0的差异即为典型案例; - 双源交叉核对:
uv.lock来源(声明层)与.venv来源(安装层)的版本差异(如前文 aiohttp、click 的例子)提示环境存在漂移,可据此检查 requirements.txt、deploy/docker/requirements.txt 与 lock 文件的一致性; - 许可证缺口识别:对缺失
licenses字段的 500 余个组件,应回到源包元数据单独确认许可证,而不是默认宽松; - CI 供应链审计:通过
syft:location定位到 .github/workflows/main.yml、.github/workflows/release.yml、.github/workflows/docker-release.yml 的 Action 引用,逐一核对第三方 Action 的版本与可信度。
七、小结
Crawl4AI 的 sbom/ 目录提供了一份规范版本为 CycloneDX 1.6、由 syft 1.40.1 生成的全仓库 SBOM:它把 679 个组件(278 个库、385 个文件、16 个应用/二进制)、140 条依赖关系,以及从 uv.lock、.venv、Docker requirements 到 GitHub Actions 的四条依赖面,统一收录进 sbom/sbom.cdx.json,并可通过 scripts/gen-sbom.sh 一键再生成。理解其 best-effort 快照属性、组件溯源属性(syft:location、syft:package:foundBy)与许可证覆盖缺口,是在这个仓库上做好供应链透明度评估的基本功。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00