Linux syft 的 CycloneDX / SPDX 输出与供应链安全报告生成

2次阅读

syft生成cyclonedx和spdx的关键区别在于:cyclonedx需显式指定版本(如-o cyclonedx-json@1.5)以确保含bomformat/specversion字段;spdx默认输出2.3 json,spdx-yaml会静默降级为json,且licenseconcluded恒为noassertion。

Linux syft 的 CycloneDX / SPDX 输出与供应链安全报告生成

syft 生成 CycloneDX 和 SPDX 的命令区别在哪

syft 默认输出是 table 格式,不带 SBOM 元数据;要生成合规的 CycloneDX 或 SPDX,必须显式指定输出格式和 schema 版本,否则下游工具(比如 Dependency-Track、Syft CLI 自身的 --output)会报错或解析失败。

  • syft <strong>your-image</strong> -o cyclonedx 输出 CycloneDX v1.4 JSON(默认),但不含 bomFormat / specVersion 字段时可能被某些解析器拒收
  • syft <strong>your-image</strong> -o cyclonedx-json@1.5 才能生成符合 CycloneDX 1.5 规范的 JSON(含完整元数据)
  • syft <strong>your-image</strong> -o spdx-json 输出 SPDX 2.3 JSON,但注意:syft 当前(v1.9+)不支持 SPDX 2.2 YAML,spdx-yaml 会静默退化为 JSON
  • 若用 -o spdx-tag-value,输出的是 SPDX 2.3 tag-value 格式,人类可读但机器解析兼容性弱于 JSON

CycloneDX 输出里 missing bom-refcomponents 为空

常见于扫描容器镜像时未指定 registry 凭据,或镜像层被缓存但未触发完整解包;syft 会跳过无法访问的 layer,导致组件列表为空,但不报错,只输出空 components: []

  • 先确认是否能拉取镜像:docker pull <strong>your-image</strong>podman pull <strong>your-image</strong>
  • 若用私有 registry,必须传 --registry-auth-file ~/.docker/config.json(注意路径权限,syft 不读 $HOME/.docker/config.json 自动)
  • --scope all-layers 强制扫描所有层(默认只扫最上层),尤其对 multi-stage 构建的镜像有效
  • 检查输出是否含 "bomFormat": "CycloneDX""specVersion": "1.5" —— 缺任一字段都说明格式未真正生效

SPDX 输出中 licenseConcluded 总是 NOASSERTION

syft 不做许可证推断,只基于文件级声明(如 package.jsonsetup.pygo.mod)提取已知字段;没有显式声明的地方一律填 NOASSERTION,这是 SPDX 规范要求,不是 bug

  • Go 项目需确保 go.mod 里有 //go:license MIT 注释(syft 支持该约定),否则 go 模块 license 为空
  • Python 包依赖的 license 来自 pip show <strong>pkg</strong> 输出,若 PyPI 元数据缺失(如未填 classifiers),syft 就拿不到
  • 不要指望 syft 从 LICENSE 文件内容反向识别 license 类型 —— 它不做 nlp 或正则匹配,只查结构化元数据
  • 如需更准的 license 信息,得在生成 SBOM 后用 syft <strong>image</strong> | grype - 补充漏洞上下文,但 license 本身不会变

把 syft 输出喂给供应链安全平台时校验失败

Dependency-Track、FOSSA 等平台对 CycloneDX/SPDX 的 schema 严格校验,syft 默认输出可能缺必要字段(如 serialNumbermetadata.timestamp),导致上传后被拒绝。

  • --file bom.cdx.json 并配合 -o cyclonedx-json@1.5,syft 会自动补全 serialNumber(UUIDv4)和 metadata
  • SPDX 必须含 "SPDXID": "SPDXRef-DOCUMENT""documentNamespace" —— syft 生成时会自动设,但若重定向到文件再手动编辑,容易删掉
  • 避免用 syft ... | jq '.' > bom.json 管道处理,jq 可能破坏 UTF-8 BOM 或换行符,某些平台校验失败就卡在这
  • 上传前用官方校验器快速过一遍:curl -s https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.34.0/cyclonedx-cli_0.34.0_linux_amd64.tar.gz | tar -xz && ./cyclonedx-cli validate -i bom.cdx.json

SBOM 不是“生成了就完事”,CycloneDX 和 SPDX 的每个字段都有语义约束;syft 做得足够轻量,但也意味着它不会替你猜意图——参数写错一位、schema 版本漏一个 @ 符号、registry 凭据路径少个点,结果就是下游平台报错却找不到源头。盯着输出里的 bomFormatspecVersion 多看两眼,比反复重跑快得多。

text=ZqhQzanResources