FDE Times 数据在招 FDE 职位 838▼55 近 7 天在招职位数的变化(同口径比较):不计入本周新开始追踪的公司的职位近 7 天新增 66在招公司 169支持远程 24%美国薪资中位数 $200k招聘最多 Palantir 95
ENVI

前线部署工程师(FDE)的专业媒体

技能指南 · 指南

客户问你交付了什么,让 SBOM 来回答

软件清单要真正有用,就得列出你从没选过的库,以及每个库是怎么引入的。

分享微博

要点速览

  • NTIA 对 SBOM 的定义包含供应链关系,合规的 SBOM 必须列出全部传递依赖,而不只是最上层。
  • 欧盟 CRA 的底线只要求顶层依赖;德国 BSI 的指南要求在每条分支上递归解析,至少解析到交付范围之外的第一个组件。
  • 扁平或过时的 SBOM 会拖慢事件响应,因此每次打补丁后都要重新生成,并写明清单没有覆盖哪些内容。
对比表,比较回答“这次发布包含什么”的三种方式。requirements.txt 文件只列出直接依赖包。扁平 SBOM 同时列出直接和传递依赖包,但看不出该升级哪个包。只有带依赖关系的 SBOM 通过全部三项检验:列出直接依赖包、列出传递依赖包,并能指出为移除有漏洞的传递包应升级哪个直接依赖。
清单文件会漏掉传递依赖包。扁平 SBOM 列出了所有包,却没有记录谁引入了谁,因此出现漏洞时说不出该升级什么。资料来源:DevGuard、SafeDep、NTIA,据本文。

设想上线前的最后一周。数据管道已经搭好,Agent 在客户的真实数据上跑得很顺,这时客户的安全团队发来一封只有一句话的邮件:“你们交付的东西里到底有什么?”

最顺手的做法,是把 requirements.txt 或 package.json 直接贴进回信正文。又快,看起来也完整。但 DevGuard 的文档指出,传递依赖包不会出现在这类顶层声明文件里;除非刻意展开,依赖树始终是隐藏的。

这里考验的不是跑一条命令生成一个文件,而是弄懂客户真正在问什么,交付一份对方工具能读取的清单,并且在客户发现之前,就知道自己的清单哪里有盲区。

客户问的其实是“关系”

NTIA(美国国家电信和信息管理局)2021 年的报告把 SBOM 定义为一份正式记录,包含构建软件所用组件的详情及其供应链关系。

“关系”写在定义里,不是事后补充。NTIA 最低要素中的依赖关系字段,描述的是上游组件如何被纳入软件。

在深度上,根据 FOSSA 的总结,符合 NTIA 要求的 SBOM 必须包含所有顶层组件和全部传递依赖,或者提供足以追溯它们的信息。贴进邮件的清单文件只满足了前一半。

风险恰恰在后一半。安全工具厂商 DevGuard 认为,典型应用中绝大多数有漏洞的包都是传递依赖。这是厂商的说法,不是独立研究,但打印过依赖树的人都知道,自己亲手选的包只是冰山一角。

清单还得说明自己从哪来

CISA(美国网络安全和基础设施安全局)2025 年的最低要素以 NTIA 2021 为基础,强调采用机器可处理的格式,让 SBOM 能大规模接入工具链。根据 Sonatype 的总结,2025 版新增了四个字段:Component Hash、License Information、Tool Name 和 Generation Context。每个字段都对应客户通常会紧接着第一个问题追问的事。

CISA 2025 年新增字段 客户真正想问的
Component Hash 这个文件和你们检查过的是同一个吗?
License Information 我们可以使用、修改和再分发它吗?
Tool Name 这份清单是哪个工具生成的,可信吗?
Generation Context 在什么上下文中生成:从源码还是从构建产物?

实际的结论是:不要发一份只给人看的文档。先问客户安全团队把 SBOM 导入哪个工具、用什么格式,然后按这个格式交付。项目启动时问一句,就省掉了最后关头的一轮格式转换。

逐行走一遍交付物

假设你交付一个容器,里面是一个内部 RAG 服务。该服务直接声明了一个 PDF 解析库,而这个库又引入了一个你从没提过的图像处理库。以下包名均为虚构:

rag-service 1.0.0
└── example-pdf-parser 2.4.1      (直接依赖)
    └── example-image-lib 0.9.2   (传递依赖)  ← 存在已公开漏洞

如果清单是扁平列表,两个包都在,但没人看得出谁引入了谁。SafeDep 认为,扁平 SBOM 掩盖了“升级哪个直接依赖才能移除有漏洞的传递包”这一信息,从而拖长事件响应。

记录了依赖关系,答案一目了然:把 example-pdf-parser 升级到不再引入 example-image-lib 0.9.2 的版本。

漏洞也不是全部。SafeDep 还指出,恶意软件、过时的库和许可证问题也常藏在这个盲区里。假设 example-image-lib 采用 copyleft 许可证,而合同写明客户会把交付物重新打包给子公司使用:清单文件永远不会让你看到这个冲突。

这时你的任务不是自己做法律判断。标出这个组件,有替代方案就找出来,并在文件发给客户之前告知己方负责法务的人。由你发现,它只是技术说明里的一行;由客户先发现,整个交付都会受到质疑。

CRA 设的是底线,不是上限

对于向欧盟销售产品的客户,《网络弹性法案》(CRA)就是这个问题必然会来的原因。根据 FOSSA 的说法,CRA 附件 I 要求 SBOM 至少覆盖顶层依赖。“至少”是法律底线,不是完整清单。

德国网络安全机构 BSI 的指南 TR-03183-2 走得更远,尽管它没有约束力,也不是欧盟法律:依赖必须在每条分支上递归解析,至少解析到交付范围之外的第一个组件。

对前线部署工程师(FDE)来说,这是更实用的标尺,因为它问的是交付物里有什么,而不只是你选了什么。

所以即便客户只要求 CRA 的最低标准,也要生成完整的依赖树。上线后如果三层之下的某个依赖曝出漏洞,要想办法把它移除的人还是你。

发出文件前的五个步骤

  1. 项目启动时,问清客户用什么工具和格式导入 SBOM。
  2. 在构建阶段,基于你实际要交付的产物生成 SBOM,而不是在开发机上生成,并记录工具名称和生成上下文。
  3. 检查深度:清单包含传递依赖及其相互关系,每个组件都有版本、哈希和许可证。
  4. 单独审查传递依赖,查看漏洞、过时版本,以及与客户预期使用方式冲突的许可证。
  5. 写一份简短的范围说明,写明清单覆盖到多深、不包括哪些内容、何时生成;每次打补丁后,从第 2 步重新开始。

让清单适得其反的错误

最常见的错误,是交付一次 SBOM 就当作完事。Sonatype 提醒,低质量的 SBOM 就是不完整、不准确或已过时的 SBOM。每次你在客户现场给某个依赖打补丁却不重新生成,旧清单就会三条全占,制造虚假的安全感。

其次是因为 CRA 写的是“至少顶层”,就只列直接依赖。这只是保持合规的最低要求,而客户的真实风险在传递依赖及其相互关系里。只有顶层的清单合法,却回答不了客户真正在问的问题。

第三是包都列全了,却丢掉了关系,得到的就是扁平 SBOM。一旦出事,客户团队只能自己重建依赖树来判断该升级什么,而那恰恰是他们最没时间的时候。

还有一件小事值得一开始就做对:许可证用标准标识符记录,而不是写“Apache license v2”这样的自由文本。自由文本很难被客户的工具解析,又把核对工作推回给人,这与 CISA 强调的机器可处理精神背道而驰。

一项值得写进简历的技能

看 FDE 招聘启事时留意一点:岗位描述越多提到安全评审、客户采购流程或本地化部署,你就越该准备好回答“交付物里有什么”这个问题。这是从工作性质推出的判断,不是定律,面试时不妨直接问招聘经理。

简历上别写笼统的“对安全感兴趣”,而是写一行具体的:为某次交付生成并维护了包含完整传递依赖和依赖关系的 SBOM,并在客户评审前发现了一处许可证冲突。

一个附带完整依赖树 SBOM 和范围说明的个人项目,比任何自我描述都更容易验证。

下次再收到那封一句话的邮件,你不会再贴 requirements.txt。你会发出一个客户工具可以直接加载的文件,并附上一行说明:清单覆盖到多深,不包括什么。

这篇文章对你有帮助吗?

7 个信源
路线图上的下一篇 · 阶段 5: 部署上线安装之前,先让客户的机器说真话一个只读 bash 脚本把每项检查评为 PASS、WARN 或 FAIL,只有 FAIL 能叫停安装。