275 lines
12 KiB
ReStructuredText
275 lines
12 KiB
ReStructuredText
PEP: 761
|
|
Title: Deprecating PGP signatures for CPython artifacts
|
|
Author: Seth Michael Larson <seth@python.org>
|
|
Sponsor: Hugo van Kemenade
|
|
Discussions-To: https://discuss.python.org/t/pep-761-deprecating-pgp-signatures-for-cpython-artifacts/67180
|
|
Status: Draft
|
|
Type: Process
|
|
Created: 08-Oct-2024
|
|
Python-Version: 3.14
|
|
Post-History: `25-Sep-2024 <https://discuss.python.org/t/pre-pep-discussion-stop-providing-gpg-signatures-for-cpython-artifacts/65058>`__, `09-Oct-2024 <https://discuss.python.org/t/pep-761-deprecating-pgp-signatures-for-cpython-artifacts/67180>`__
|
|
|
|
Abstract
|
|
========
|
|
|
|
Since Python 3.11.0, CPython has provided two verifiable digital signatures
|
|
for all CPython artifacts: PGP and Sigstore.
|
|
|
|
PGP's design requires the maintenance and protection of `long-lived private
|
|
keys <https://words.filippo.io/giving-up-on-long-term-pgp/>`_ by trusted
|
|
parties. PGP's `security and ergonomics have been criticized by security
|
|
practitioners <https://www.latacora.com/blog/2019/07/16/the-pgp-problem/>`_
|
|
for many years now, with the biggest issue being that there were few
|
|
alternatives for "artifact signing" being proposed or adopted.
|
|
|
|
`Sigstore's <https://docs.sigstore.dev>`_ design philosophy has focused on the
|
|
ergonomics of signing and verifying and `uses short-lived keys with
|
|
strongly-bound human-readable identities via OpenID Connect <https://docs.sigstore.dev/#how-sigstore-works>`_.
|
|
Sigstore has both development and adoption momentum, seeing adoption by PyPI,
|
|
NPM, Homebrew, and GitHub, among other ecosystems.
|
|
|
|
This PEP proposes to move CPython to using Sigstore exclusively for signing
|
|
artifacts through a deprecation and eventual discontinuance of providing PGP
|
|
signatures with new release managers.
|
|
|
|
Motivation
|
|
==========
|
|
|
|
CPython's releases are release-manager-centric, where a single person
|
|
maintains multiple CPython releases from pre-release to end-of-life over the
|
|
course of many years.
|
|
|
|
Requiring release managers to maintain and protect PGP private keys for seven
|
|
or more years is an unnecessary burden in the new age of ergonomic and
|
|
ephemeral signing keys. Comparatively, Sigstore only requires release managers
|
|
to click a button during the release process to OAuth sign-on to their
|
|
identity provider. Maintaining the integrity of accounts on identity providers
|
|
like GitHub is already an expectation of being a Python release manager or
|
|
core team member, such as through multi-factor authentication and strong
|
|
unique passwords.
|
|
|
|
Rationale
|
|
=========
|
|
|
|
Preserve expectations across a Python release
|
|
---------------------------------------------
|
|
|
|
To avoid breaking downstream verifiers, the expectations for verification
|
|
materials availability SHOULD NOT be changed during a feature release's
|
|
lifecycle.
|
|
|
|
Release managers, not releases
|
|
------------------------------
|
|
|
|
The discontinuation of PGP signatures doesn't necessarily have to happen
|
|
on a "release manager boundary"; a new Python release could be a potential
|
|
boundary.
|
|
|
|
Because the primary motivation for deprecating PGP is ergonomics, deciding
|
|
to drop PGP for one release while a release manager still has obligations to
|
|
provide PGP signatures for other releases for multiple years isn't much
|
|
savings of effort.
|
|
|
|
A new release manager also represents a new PGP public key that downstream
|
|
verifiers need to adopt. By choosing to make the change during this period,
|
|
this minimizes the breakage to a place in downstream maintenance where a
|
|
change will already be necessary.
|
|
|
|
Gordian knot of signing methods and verifiers
|
|
---------------------------------------------
|
|
|
|
CPython providing both PGP and Sigstore signatures concurrently creates a
|
|
"`Gordian knot <https://en.wikipedia.org/wiki/Gordian_Knot>`_" where
|
|
verifiers are disincentivized to migrate to a new signature method due to the
|
|
*continued and expected availability* of an existing signature method, thus
|
|
propagating the *apparent demand* for maintaining the existing signature
|
|
method.
|
|
|
|
This situation slows down the adoption of new signature methods like Sigstore for
|
|
both signature-producing projects and signature-verifying ecosystems by not
|
|
creating a "need" to automate and integrate the signature method into verifier
|
|
tooling.
|
|
|
|
By changing the expectation of what future signature methods will be
|
|
available, the incentive-knot can be broken by `spurring the adoption of the
|
|
new signature method in downstream tooling <https://lists.debian.org/debian-devel/2024/10/msg00025.html>`_.
|
|
This change to verifier tooling also makes other upstream projects able to
|
|
migrate to publishing only Sigstore signatures, resulting in a positive
|
|
feedback loop of adoption.
|
|
|
|
Specification
|
|
=============
|
|
|
|
Because PGP keys are tied to a release manager identity, the change to
|
|
availability of PGP signatures will be tied to release managers instead of
|
|
individual releases (3.13, 3.14, etc). This PEP both deprecates and proposes
|
|
a discontinuation timeline for PGP signatures.
|
|
|
|
Deprecation and discontinuation of PGP signatures
|
|
-------------------------------------------------
|
|
|
|
This PEP deprecates PGP signatures for future CPython releases and recommends
|
|
verifiers to adopt Sigstore to verify CPython artifacts as an alternative to
|
|
PGP.
|
|
|
|
This PEP also removes the expectation that PGP signatures be published by
|
|
future release managers that don't already maintain a stable Python release.
|
|
At the time of writing this would be Hugo van Kemenade, as 3.14 is the next
|
|
Python version without a stable release.
|
|
|
|
Releases which already have a stable release (3.13, 3.12, 3.11, etc) are not
|
|
affected and will continue to provide PGP signatures for artifacts until they
|
|
are end-of-life. All existing PGP signatures will continue to work as
|
|
expected.
|
|
|
|
Delaying discontinuation of PGP signatures
|
|
------------------------------------------
|
|
|
|
This PEP provides a mechanism to delay the *discontinuation* of PGP signatures
|
|
from active and upcoming CPython releases in case of extraordinary
|
|
circumstances. *Deprecation* of PGP signatures can't be changed without a
|
|
superseding PEP.
|
|
|
|
The Steering Council MAY at a future date after this PEP's acceptance decide
|
|
to delay the discontinuation of PGP signatures to a future CPython release.
|
|
If the Steering Council decides to delay the discontinuation of PGP signatures
|
|
then all active release managers MUST provide PGP signatures for their covered
|
|
CPython artifacts for the remainder of their tenure as a release manager. This
|
|
includes all steps required to do so, such as generating a new PGP key and
|
|
publishing their identity to python.org.
|
|
|
|
The discontinuation of PGP signatures then is automatically scheduled for the
|
|
next release manager without a stable release, to be highlighted in the
|
|
Steering Council decision.
|
|
|
|
Backwards Compatibility
|
|
=======================
|
|
|
|
This proposal would remove the ability to verify future CPython artifacts
|
|
using PGP. Any downstream verifiers using PGP for CPython artifacts would
|
|
need to either start using Sigstore, verify their source code of CPython
|
|
through other means, or stop verification altogether for future CPython
|
|
releases.
|
|
|
|
Security Implications
|
|
=====================
|
|
|
|
PGP and Sigstore have different security models, so by removing PGP
|
|
signatures this means that all users only have the option to rely on the
|
|
security model provided by Sigstore.
|
|
|
|
In general, the security model required for artifact signatures is being
|
|
able to detect whether a given artifact is from the expected source and
|
|
hasn't been modified, regardless of the security or integrity of the hosting
|
|
service (in CPython's case: python.org/downloads).
|
|
|
|
`Sigstore's security model <https://docs.sigstore.dev/about/security/>`_
|
|
depends more on centralized infrastructure compared to PGP, such as the
|
|
"public good" signature transparency log (Rekor), certificate authority and
|
|
transparency log (Fulcio), and the security of OpenID Connect identity
|
|
providers like Google and GitHub.
|
|
|
|
CPython's development already depends on the security of some of these
|
|
services and the others are better resourced than any individual release
|
|
manager to provide long-term public key management.
|
|
|
|
How to Teach This
|
|
=================
|
|
|
|
CPython `already documents <https://www.python.org/downloads/metadata/sigstore/>`_
|
|
how to verify artifacts using Sigstore based on the pre-published identities
|
|
of release managers. Documentation will be updated to indicate the deprecation
|
|
and future expectations of PGP signatures.
|
|
|
|
Verifying signatures of CPython artifacts isn't something we should expect
|
|
from new Python users. Instead, Sigstore is more likely to be a part of a
|
|
downstream integrator's build pipeline such as a Linux distro, Homebrew, pyenv,
|
|
or others that programmatically fetch and build CPython from source.
|
|
|
|
Rejected Ideas
|
|
==============
|
|
|
|
Continue publishing PGP signatures indefinitely
|
|
-----------------------------------------------
|
|
|
|
Being a release manager is already a difficult, time-consuming, and long-term
|
|
commitment that is typically done on a volunteer basis. Thus we see removal
|
|
of PGP key management duties as a step towards reducing burnout and stress
|
|
of future release managers and improving the sustainability of CPython.
|
|
|
|
Removing previous PGP signatures
|
|
--------------------------------
|
|
|
|
This PEP doesn't intend to break any infrastructure built around existing Python
|
|
versions, instead only changing the expectations around future Python versions.
|
|
Thus all PGP signatures that are already available on python.org will continue
|
|
to be available even after PGP discontinuance.
|
|
|
|
Appendix
|
|
========
|
|
|
|
Support for offline verification
|
|
--------------------------------
|
|
|
|
During the `pre-PEP discussion <https://discuss.python.org/t/pre-pep-discussion-stop-providing-gpg-signatures-for-cpython-artifacts/65058>`_,
|
|
there was a question of whether offline verification was supported by
|
|
Sigstore. Using a Sigstore bundle (:file:`.sigstore`) file, `Sigstore clients
|
|
support verifying the artifact completely offline <https://discuss.python.org/t/pre-pep-discussion-stop-providing-gpg-signatures-for-cpython-artifacts/65058/9>`_.
|
|
|
|
Using offline verification with Sigstore requires disabling root of trust
|
|
updates and "pinning" a root of trust in a file to use during verification.
|
|
|
|
Pinning a root of trust means signatures made after a *new* root of trust
|
|
is established would no longer be able to verify using a "pinned" previous
|
|
root of trust. New roots of trust are expected to be rare events, such as
|
|
when the root of trust is compromised, and in this case verifiers would
|
|
want signatures to fail to verify.
|
|
|
|
Offline verification also makes revocation checks impossible, but this
|
|
is similar to PGP's model where revocation of keys requires an online lookup.
|
|
|
|
Barring rare events like root of trust compromise, using offline verification
|
|
with Sigstore doesn't impose additional operations requirements to verifiers.
|
|
|
|
Support for a pre-compiled executable for verification
|
|
------------------------------------------------------
|
|
|
|
During discussion there were requests for a pre-compiled executable that could
|
|
be used for verifying Sigstore bundles without needing to either install
|
|
a Go build toolchain to build `sigstore-go <https://github.com/sigstore/sigstore-go>`_
|
|
from source or already have a working Python installation for
|
|
`sigstore-python <https://github.com/sigstore/sigstore-python/>`_.
|
|
|
|
`Cosign <https://github.com/sigstore/cosign/>`_ is another Sigstore project
|
|
that provides pre-compiled standalone binaries and supports verifying bundles
|
|
offline:
|
|
|
|
.. code-block::
|
|
|
|
# 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://accounts.google.com' \
|
|
--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
|
|
|
|
Copyright
|
|
=========
|
|
|
|
This document is placed in the public domain or under the
|
|
CC0-1.0-Universal license, whichever is more permissive.
|