Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 761 – 弃用 CPython 构件的 PGP 签名

作者:
Seth Michael Larson <seth at python.org>
发起人:
Hugo van Kemenade
讨论至:
Discourse 帖子
状态:
活跃
类型:
流程
创建日期:
2024年10月8日
Python 版本:
3.14
发布历史:
2024年9月25日2024年10月9日
决议:
2024年11月6日

目录

摘要

自 Python 3.11.0 起,CPython 为所有 CPython 构件提供了两种可验证的数字签名:PGP 和 Sigstore。

PGP 的设计要求受信任方维护和保护长期私钥。多年来,PGP 的安全性与人体工程学一直受到安全专业人士的批评,最大的问题是当时很少有“构件签名”的替代方案被提出或采纳。

Sigstore 的设计理念专注于签名和验证的人体工程学,并通过 OpenID Connect 使用带有强绑定、人类可读身份的短时密钥。Sigstore 兼具开发和采用的势头,已获得 PyPI、NPM、Homebrew 和 GitHub 等生态系统的采用。

本 PEP 提议 CPython 专门使用 Sigstore 进行构件签名,通过弃用并最终停止为新的发布管理器提供 PGP 签名。

动机

CPython 的发布以发布管理器为中心,一个人在多年时间内维护多个 CPython 版本,从预发布到生命周期结束。

在人体工程学和临时签名密钥的新时代,要求发布管理器维护和保护 PGP 私钥长达七年或更长时间是不必要的负担。相比之下,Sigstore 只要求发布管理器在发布过程中点击一个按钮,即可通过 OAuth 登录其身份提供商。维护 GitHub 等身份提供商账户的完整性已经是 Python 发布管理器或核心团队成员的预期职责,例如通过多因素身份验证和强大的唯一密码。

基本原理

在 Python 版本发布期间保持预期

为避免破坏下游验证器,在功能版本的生命周期内,不应更改验证材料可用性的预期。

版本管理器,而非版本本身

PGP 签名的停止不一定必须发生在“发布管理器边界”;新的 Python 版本可能是一个潜在的边界。

由于弃用 PGP 的主要动机是人体工程学,如果发布管理器仍然有义务在多年内为其他版本提供 PGP 签名,那么决定为某个版本放弃 PGP 并不会节省太多精力。

新的发布管理器也代表着下游验证器需要采纳的新 PGP 公钥。通过选择在此期间进行更改,可以将破坏降到下游维护中已经需要更改的地方。

签名方法和验证器的戈尔迪结

CPython 同时提供 PGP 和 Sigstore 签名会造成一个“戈尔迪结”,由于现有签名方法的持续和预期可用性,验证者被劝退迁移到新的签名方法,从而传播了维护现有签名方法的“表观需求”。

这种情况阻碍了 Sigstore 等新签名方法在签名生成项目和签名验证生态系统中的采用,因为它没有创造“需求”将签名方法自动化并集成到验证工具中。

通过改变对未来可用签名方法的预期,可以通过促使下游工具采用新的签名方法来打破激励结。这种对验证工具的改变也使得其他上游项目能够迁移到只发布 Sigstore 签名,从而形成积极的采用反馈循环。

规范

由于 PGP 密钥与发布管理器身份绑定,PGP 签名的可用性变更将与发布管理器而非单个版本(3.13、3.14 等)绑定。本 PEP 既弃用了 PGP 签名,也提出了其停止使用的时间线。

PGP 签名的弃用与停止

本 PEP 弃用未来 CPython 版本的 PGP 签名,并建议验证者采用 Sigstore 作为 PGP 的替代方案来验证 CPython 构件。

本 PEP 还取消了未来发布管理器(尚未维护稳定 Python 版本)发布 PGP 签名的预期。在撰写本文时,这将是 Hugo van Kemenade,因为 3.14 是下一个没有稳定版本的 Python 版本。

已发布稳定版本(3.13、3.12、3.11 等)不受影响,将继续为构件提供 PGP 签名,直至其生命周期结束。所有现有的 PGP 签名将继续按预期工作。

推迟停止 PGP 签名

本 PEP 提供了一种机制,可在特殊情况下推迟主动和即将推出的 CPython 版本中 PGP 签名的

停止

PGP 签名的弃用

无法在没有后续 PEP 的情况下更改。

指导委员会可在本 PEP 获得批准后的未来某个日期,决定将 PGP 签名的停止推迟到未来的 CPython 版本。如果指导委员会决定推迟 PGP 签名的停止,则所有现任发布经理必须在其任期内为其负责的 CPython 构件提供 PGP 签名。这包括执行此操作所需的所有步骤,例如生成新的 PGP 密钥并将其身份发布到 python.org。

PGP 签名的停止将自动安排给下一个没有稳定版本的发布经理,并在指导委员会的决定中重点说明。

向后兼容性

此提案将取消使用 PGP 验证未来 CPython 构件的能力。任何使用 PGP 验证 CPython 构件的下游验证者将需要开始使用 Sigstore,通过其他方式验证其 CPython 源代码,或者完全停止对未来 CPython 版本的验证。

安全隐患

PGP 和 Sigstore 具有不同的安全模型,因此取消 PGP 签名意味着所有用户只能选择依赖 Sigstore 提供的安全模型。

一般来说,构件签名所需的安全模型是能够检测给定构件是否来自预期来源且未被修改,而无论托管服务(在 CPython 的情况下:python.org/downloads)的安全性或完整性如何。

Sigstore 的安全模型更依赖于集中式基础设施,而非 PGP,例如“公共利益”签名透明日志(Rekor)、证书颁发机构和透明日志(Fulcio),以及 OpenID Connect 身份提供商(如 Google 和 GitHub)的安全性。

CPython 的开发已经依赖于其中一些服务的安全性,而其他服务则比任何个人发布管理器拥有更好的资源来提供长期公钥管理。

如何教授此内容

CPython已经记录了如何根据预发布的发布管理器身份使用 Sigstore 验证构件。文档将更新以指示 PGP 签名的弃用和未来的预期。

验证 CPython 构件的签名并非我们应该期望新 Python 用户完成的任务。相反,Sigstore 更可能成为下游集成商构建流程的一部分,例如 Linux 发行版、Homebrew、pyenv 或其他以编程方式从源代码获取和构建 CPython 的工具。

被拒绝的想法

无限期继续发布 PGP 签名

成为一名发布经理本身就是一项艰巨、耗时且长期的承诺,通常是基于志愿精神。因此,我们认为取消 PGP 密钥管理职责是减少未来发布经理的倦怠和压力,并提高 CPython 可持续性的一步。

移除以前的 PGP 签名

本 PEP 无意破坏任何围绕现有 Python 版本构建的基础设施,而只是改变对未来 Python 版本的预期。因此,所有已在 python.org 上可用的 PGP 签名即使在 PGP 停止使用后仍将继续可用。

附录

支持离线验证

PEP 前讨论期间,有人提出了 Sigstore 是否支持离线验证的问题。使用 Sigstore 捆绑包(.sigstore)文件,Sigstore 客户端支持完全离线验证构件

使用 Sigstore 进行离线验证需要禁用信任根更新,并将信任根“固定”在一个文件中以供验证时使用。

固定信任根意味着在新信任根建立后生成的签名将无法使用“固定”的先前信任根进行验证。新的信任根预计是罕见事件,例如信任根受到威胁时,在这种情况下,验证者会希望签名验证失败。

离线验证也使得撤销检查变得不可能,但这类似于 PGP 的模型,其中密钥的撤销需要在线查找。

除了信任根受损等罕见事件外,使用 Sigstore 进行离线验证不会给验证者带来额外的操作要求。

支持用于验证的预编译可执行文件

在讨论期间,有人要求提供一个预编译的可执行文件,用于验证 Sigstore 捆绑包,而无需安装 Go 构建工具链来从源代码构建sigstore-go,或已有一个可用的 Python 安装用于sigstore-python

Cosign是另一个 Sigstore 项目,它提供预编译的独立二进制文件并支持离线验证捆绑包

# Download Cosign
wget https://github.com/sigstore/cosign/releases/download/v2.4.1/cosign-linux-amd64

# For offline verification, also need the Root of Trust. Can be grabbed
# from GitHub at: https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json
wget https://raw.githubusercontent.com/sigstore/root-signing/refs/heads/main/targets/trusted_root.json

# Download CPython artifacts
wget https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tgz
wget https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tgz.sigstore

./cosign-linux-amd64 verify-blob \
  --new-bundle-format \
  --certificate-oidc-issuer 'https://#' \
  --certificate-identity 'thomas@python.org' \
  --bundle ./Python-3.13.0.tgz.sigstore \
  # --offline and --trust-root optional for offline verification
  --offline \
  --trust-root ./trusted_root.json \
  ./Python-3.13.0.tgz

来源:https://github.com/python/peps/blob/main/peps/pep-0761.rst

最后修改时间:2024-11-06 19:20:02 GMT