☰
PyPI 供应链安全未来五年:从 PEP 740 Attestations 到索引级二元透明日志
2026/10/14 22:55:45 网站建设 项目流程

【免费下载链接】publications

Publications from Trail of Bits

项目地址:https://gitcode.com/GitHub_Trending/pu/publications
点击查看免费下载

本文基于 Trail of Bits 开源出版物仓库中收录的 SigstoreCon 2024 演讲《The Next 5 Years of Supply Chain Security on PyPI》(演讲者:William Woodruff,README、slides.pdf)展开。PyPI 在过去五年密集引入了 scoped API tokens、安全事件告警、强制 MFA、Trusted Publishing 以及 PEP 740 包级加密证明(attestations)等一系列机制;本文将完整梳理这套演进时间线,解释每个机制解决了什么威胁,并重点解析演讲提出的三大五年目标——扩展 attestation 的广度与深度、把验证能力下沉到pip等下游用户工具、以及建立 Gosumdb风格的索引级二元透明(binary transparency),帮助读者理解 Python 打包生态供应链安全的现状、瓶颈与演进方向。

背景:PyPI 不是一个工具,而是一整套标准驱动的生态

理解"下一个五年"的规划,先要理解 PyPI 和 Python 打包生态的基本盘。演讲给出的关键事实(截至 2024 年 11 月):

  • PyPI(读作 "Pie-pea-eye")是pip install背后的官方包索引,规模约为 86 万用户、57.5 万项目、610 万 releases、1220 万文件;
  • 每月下载量约 510 亿次,日均流量超过 2TB(演讲指出这部分数字因大量工具和大型 CI/CD 提供商缓存不足而有所虚高)。

PyPI 只是 Python 打包"星丛"(constellation)中的一块拼图,其余部件包括:

  • 安装器(installers):pip、uv、poetry等;
  • 构建工具与后端(build tools and backends):setuptools、hatch、flit、poetry等;
  • 上传工具(upload tools):twine、uv、poetry等。

很少有单一工具能覆盖全部环节(尽管正在缓慢变化)。更关键的是 Python 打包是标准驱动的:Python Enhancement Proposals(PEPs)一旦被接受,就成为 PyPA(Python Packaging Authority)的"活标准"。这与 Rust(cargo)和 JavaScript(npm)的自顶向下、由官方工具主导的模式不同。

Python 社区庞大且高度多元——经验、背景、兴趣、技能、投入时间的各种组合并存,"为生态找到一个安全问题的公共分母"本身就极其困难。演讲者甚至类比:这个生态更接近"一个国家甚至多个国家",而非其他软件生态。

方法论:把安全问题当作可用性问题解决

这是整场演讲的立论基础,也是理解后续所有机制设计取舍的钥匙:

  • Python 生态的多元性既是其优势,也是系统性安全变革的挑战;缺乏系统性规划会自我强化——因为任何新的系统性方案都必须兼容既有约定与期望;
  • 另一方面,激进的系统性规划会伤害生态健康:惩罚性的安全要求(onerous security requirements)会把新人吓跑。

由此得出的核心结论是:要让打包安全取得系统性进展,必须把安全当作一个可用性问题(usability problem)来解决。社区可以分成两个人群:

  1. 爱好者(enthusiasts):占 1%~5%,会主动采用新事物。好消息是大多数头部包由这个人群维护;坏消息是他们在全部包维护者中占比极小。
  2. 其余所有人:占 95%~99%,只关心自己工作流的可靠性;除非安全变更让他们的工作流更容易,否则不会接受要求显著行为改变的新机制。好消息是:一旦真的变简单了,他们会欣然采用。

这解释了为什么 PyPI 近几年的标志性进展——Trusted Publishing 和 PEP 740——都被刻意设计为"默认开启、零额外配置"的形式。

过去:PyPI 打包安全的演进时间线

演讲回顾了从 2003 年至今的关键节点,这条时间线值得完整保留,因为它展示了"把安全当可用性问题"策略的实际落地路径:

时间事件
2003 年前后PyPI 诞生(更非正式的前身打包方式可追溯到 1998 年)
2005PyPI 开始直接托管文件(此前只是指向其他托管方的索引),早期是 HTTP + 跳转随机服务器
2013 年前后PyPI 引入 HTTPS,对 Web 用户强制、对pip和easy_install默认启用
2015PEP 503 标准化索引 API(包含文件摘要 digests);PEP 470 正式弃用外部托管并移除残留外链
2017PyPI 重写(从 "legacy PyPI" 迁移到 Warehouse)
2018现行 PyPI 后端(Warehouse)正式上线
2019PyPI 实现并启用 MFA(TOTP + WebAuthn 物理密钥);实现 API tokens(含项目级 scoping),与用户名/密码并列为上传凭证
2020首次尝试引入 TUF(PEP 458);启动恶意软件检测/扫描的初次尝试
2022对"关键"(critical)项目强制 MFA;向指定项目免费发放 WebAuthn 令牌
2023Trusted Publishing 上线,补充(complement)手动 API tokens
2024-01-01所有项目强制 MFA;同时强制上传必须使用 API tokens 或 Trusted Publishing

两个值得注意的"弯路":2020 年基于 PEP 458(TUF)的索引签名方案最终未能在 PyPI 落地(后来被 PEP 740 路线取代),以及 PyPI 早期 PGP 签名上传的失败——后者在仓库中的 die, PGP, die 演讲中有专门论述:PGP 的设计、工具与信任模型的固有缺陷使它不适用于大规模现代生态的代码签名。

当前与进行中的工作

Verified Project URLs:让"冒充"更难

"Verified"的含义是"PyPI 能够交叉佐证这个 URL",其 ground truth 来源正是 Trusted Publishing 配置。效果是:typosquatter(typosquatting 攻击者)等冒充者即使提交内容恶意但链接"看起来很真"的项目,也难以通过验证。演讲将其影响概括为打击所谓 "starjacking" 类伪装。

PEP 740 Attestations:在 Trusted Publishing 之上"自举"包签名

这是演讲的核心现态。要点:

  • Trusted Publishing 的巨大成功本身就是可用性与安全性的双赢,因为它把"配置长期 API token"这个高危环节替换为基于 OIDC 的临时凭证(该机制的完整背景可参见仓库中 Securing your Package Ecosystem with Trusted Publishing 与 Trusted Publishing: Lessons from PyPI 两篇演讲摘要);
  • PEP 740 在 Trusted Publishing 之上自举(bootstrap)包签名:因为签名身份直接复用 Trusted Publisher,它默认覆盖了约 2 万个发布工作流,且不需要任何额外配置;
  • 底层构建在 Sigstore 之上:没有长期签名密钥,只有机器身份(Sigstore 模型在 Python 生态的早期介绍见 Ergonomic Codesigning for the Python Ecosystem with Sigstore);
  • 在演讲时点(2024 年 11 月),该功能已在 PyPI 上线约两个月。
Attestations 到底提供了什么?
  1. 可公开验证的包来源证明(provenance),语义上等价于这句话:"包 foo 版本 1.2.3 由 GitHub 仓库 foo/foo 通过工作流 pypi.yml、在 commit cafe… 时构建产出";
  2. 对索引与各个发布者的外部透明性与可审计性:每条 attestation 都有对应的 transparency log 条目可被审计审查,以及一个可被主动监控(proactively monitored)的对应机器身份。这使得攻击者即使成功入侵了某个包或其仓库,也难以"悄悄得逞";
  3. 演讲者同时保持克制:这不是万能的,因为 attestations不是(也不可能是)强制的。
上线两周的采用情况
  • PyPI 上已接收 10,000+ 条 attestations;
  • 360 个头部项目中 18 个(5%)上传了 attestations;考虑到其中约三分之二在项目启用该功能后才首次上传,也可以按 15% 解读;
  • 对仅启用两周而言,这是不错的数字。

未来五年:三个目标

目标 #1:扩展 attestations 的广度与深度(breadth/depth)

按 PEP 740 的定义,attestations 是刻意受限的(MVP 取向):

  • 只有 Trusted Publisher 可以用作签名身份;
  • attestation 谓词(predicate)刻意限定为 SLSA attestation 和 PyPI "publish" attestation 两类。

未来要扩展的方向:

  • 更多 attestation 类型:VSA(Verifiable Security Attestations,安全属性证明)?第三方 attestation,例如"该包已被某方审计评审"?
  • 更多签名身份:邮箱身份——PyPI 已经知道哪些邮箱地址完成过验证,天然可用作身份;域名身份也有可能。

README 摘要中还提到一类值得注意的设想:"counter" attestations——类似 PEP 740 但由审计者和社区成员发起,允许他们以密码学方式登记自己对某个 PyPI 包的信任,把"信任"本身也变成可验证的链式记录。

目标 #2:把验证能力带给下游用户

演讲对此的论述最为具体,也暴露了当前最大的工程瓶颈:"签名是容易的部分,验证才是难的。"

  • 索引(即 PyPI)在上传时验证 attestations 是可控的;但让pip这类用户侧代理做验证要难得多:
    • 架构约束:pip出于 vendoring(把依赖直接内置分发的历史传统)原因必须是纯 Python 的;而 Sigstore 的 Python 客户端(sigstore-python)不是纯 Python——它经由 PyCAcryptography使用 Rust 实现。这直接阻碍了pip内置验证能力;
    • 标准与工具缺失:缺少标准 lockfile 格式,使得面向用户的 "TOFU"(Trust On First Use,首次信任后锁定)验证故事难以展开——必须先有一种方式锁定"某个包预期由哪些签名身份签发"。

README 摘要把这个问题进一步展开为两条具体路线:通过 lockfiles 实现 TOFU 风格的身份锁定(可能结合 Python 的 PEP 751,即包元数据中引入 URL 规范化/锁定方向的提案);以及为 PEP 740 attestations 构建可扩展的见证(witnessing)与监控体系,包括用 rollup 技术降低pip这类纯 Python 安装器的集成负担。此外,摘要还提到使用 TUF 分发复杂的身份策略——把"哪些身份对哪些包有效"这类策略从工具代码中抽离出来、以 TUF 的元数据框架分发与更新。

目标 #3:索引级透明(index-level transparency)

Attestations 有根本性的作用域局限:

  • 不是所有人都用(或能用)Trusted Publishing——这没问题,但意味着总存在覆盖盲区;
  • 用分散在用户侧的逐包 attestation 做全索引监控几乎不可能:需要监控的签名身份数量是无界的;
  • attestations 并不能降低对索引本身的信任——PyPI 依然是高价值攻击目标(这一点在 Imagining a zero-trust future for PyPI 演讲中有更系统的"零信任未来"推演)。

演讲的结论是:我们需要无条件的透明性与真实性属性——即 PyPI 的二元透明(binary transparency):

  • 先例(prior art):Go 的sumdb、npm 的 "publish attestations"(演讲指出后者与 PyPI 的做法方向相反);
  • 理想的客户端性质:验证成本 = 1 条(或数条)ECC 签名验证 + 1 次成员证明(inclusion proof)检查,对pip这种纯 Python 安装器是可承受的;
  • 但代价同样明显:它需要一套监控与见证(witnessing)生态,而对这类生态能长期健康运行的公开证据还很薄弱("evidence for these is scant")。

"愿景"小结:今天有什么,明天要什么

演讲的收尾(the dream)把现状与目标压缩成一张对照表:

今天已经拥有:抗误用(misuse-resistant)的凭证 + 默认开启的发布 attestation——这是 Trusted Publishing + 基于 Sigstore 的索引 attestation(PEP 740)共同带来的。

明天想要:

  1. Attestations 的下游验证——今天技术上已可行,但官方包工具链尚未支持;
  2. 上游(维护者)对发布身份的监控——今天已可行,但体验不佳:Sigstore 需要一个"CI 版 Cert Spotter"(证书透明度日志监控工具)级别的能力;
  3. 索引级透明 + 健康的见证网络——需要大量设计思考,且明确向社区发出邀请:"you can help!"。

最终的终极目标,用演讲自己的话表达是能够说出这样的句子:

"when i download sampleproject v4.0.0, i know that it came from the repository it's supposed to come from and that PyPI served the same file to me as everyone else."

(当我下载 sampleproject v4.0.0 时,我知道它来自它本应来自的仓库,且 PyPI 发给我和大家的是同一个文件。)

这句话精确概括了整条技术路线的终点:provenance 由 attestation 保证,一致性由透明日志保证,验证成本被压缩到纯 Python 工具可以承担的量级。

延伸阅读:仓库内同一作者的相关演讲

本仓库(Trail of Bits publications)中收录了 William Woodruff 围绕同一主题、不同阶段的完整演讲序列,可作为本文各章节的深入阅读材料:

  • PEP 740 and PyPI: Bootstrapping Provenance for the Python Ecosystem(SOSS Fusion 2024):PEP 740 与 Sigstore、in-toto、SLSA 的集成细节,以及如何在 Trusted Publishing 之上完成 provenance 自举;
  • Attestations: a new generation of signatures on PyPI(PyCon US 2025):attestations 的架构细节、上传侧实现、安全属性与透明性,以及大规模验证这一缺口的现状;
  • Securing your Package Ecosystem with Trusted Publishing(PackagingCon 2023)与 Trusted Publishing: Lessons from PyPI(PackagingCon 2023):OIDC 临时凭证方案的安全性性质、PyPI 实现细节、多 IdP 支持与威胁模型;
  • What does it look like to code-sign for an entire packaging ecosystem?(ACM SCORED 2023):整生态代码签名的工程与现实考量(维护者运维负担、匿名生态中的身份隐私问题);
  • Ergonomic Codesigning for the Python Ecosystem with Sigstore(PyCon 2023):Sigstore 安全模型对 Python 开发者的入门;
  • die, PGP, die(SummerCon 2022):为什么 PGP 路线走不通,是现代 attestation 路线的对照面。

最后重申适用边界:本文所有规模数据(下载量、项目数、attestation 采用率等)均为演讲时点(2024 年 11 月,功能上线约两周)的快照,"未来五年"部分是演讲者的个人意见(演讲原文注明 "disclaimer: my opinions"),代表对生态演进方向的判断而非已确定的路线图;涉及 PEP 751、VSA、rollup、TUF 身份策略等内容同样属于设想阶段,落地形态以 PyPA 与 Sigstore 社区的后续标准工作为准。

【免费下载链接】publications

Publications from Trail of Bits

项目地址:https://gitcode.com/GitHub_Trending/pu/publications
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询