
A proposal for auditable package distribution on Python package indexes.
Try the test log · Read the draft PEP · View on GitHub
A transparency log can serve as a source of truth for package metadata such as artifact hashes and publishing identities:
filename: urllib3-2.7.0-py3-none-any.whl
sha256: 9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897
publisher: https://github.com/urllib3/urllib3
Currently, clients that want this metadata get it from PyPI, either by using the API or by directly downloading the artifact. Optionally, they pin it in lockfiles to ensure that future downloads match. However, this is a trust-on-first-use scheme, which leaves open the question: why should the client trust that first artifact?
A compromised index could serve different files for the same artifact to different clients:
Client A requests pkg.whl -> Index serves pkg.whl with hash X
Client B requests pkg.whl -> Index serves pkg.whl with hash Y
In this scenario, lockfiles don’t help: Clients A and B will continue to see the files they originally pinned, while the index can continue serving different files to different clients without being detected.
A transparency log provides a way to store claims like “The artifact with filename pkg.whl has a hash equal to X” such that:
The combination of these properties means that a client can verify that the package they got from PyPI has not been tampered with by the index, and is consistent with what other clients are seeing.
This solves the problem of what to use as a source of truth for package hashes and publishing identities:
The index itself (e.g. PyPI) can host and operate the log. There are a few advantages to this:
The key idea of the log is that it offers transparency: any tampering from the log operator can be trivially detected. This means the clients don’t trust the log itself, but rather the fact that they can detect if the log is misbehaving.
Since the log operator should be the index itself, having a transparency log just means that a misbehaving index can be detected, not that the index should be trusted.
It doesn’t, a compromised account will still be able to upload malicious artifacts to PyPI, and these artifacts will be added to the log. Clients that download these artifacts won’t see any problems, since they can only check if an artifact is in the log or not.
The transparency log does not protect against this type of supply chain attack, where the compromise happens before the artifact reaches the index.
However, it does make it easy for maintainers of the package to monitor the log for new entries with claims that mention the package and/or their identities. Since this monitoring can be done automatically with very little latency, maintainers can be notified of unexpected entries in the log shortly after they happen, without relying on 3rd parties noticing the compromise and notifying them.
Specifically, we say fake to mean any of:
A, but there already is an existing entry with filename A.From the configuration side, the log should be set up so that only the index can add entries. However, assuming a compromised/malicious index, there is nothing stopping the index from adding “fake” entries, the log just makes these entries discoverable.
In practical terms, this type of misbehavior should be detected by monitors of the log. A monitor can, for every entry, check that the corresponding artifact served by PyPI exists and matches the entry’s contents.
As a concrete example, let’s assume a compromised index logs an entry for pkg 2.0.0, where pkg has not released a version 2.0.0 yet. This could be in preparation to serve a malicious artifact once the pkg maintainers release version 2.0.0.
The fake entry could be detected in the following ways:
pkg monitoring new entries for claims about pkg, receiving a notification when the fake entry is added.pkg when uploading version 2.0.0 and verifying if the inclusion proof returned by the index is valid.pkg artifact in the log, but this results in duplicate entries (their claims refer to the same filename), which are trivially detectable by monitors.Maintainers are incentivized to monitor the log for claims related to the packages they maintain and their identities. However, not all maintainers will do this, and many of the security properties the log offers depend on having monitors that regularly check the log for tampering and inconsistencies like:
Luckily, there are already third parties with incentives to perform this kind of monitoring: security companies, in particular those who offer products and services related to supply chain security. These companies already monitor the index for suspicious packages, and monitoring the transparency log would be an easy and cheap addition to that.
In addition, running a monitor requires almost no mainteinance and requires very little in terms of compute, so volunteers and maintainers can easily run their own monitors for the ecosystem.
A log with 22 million entries (following the format from the draft PEP) using Ed25519 as the signing algorithm requires around:
See the Design considerations section of the PEP for more estimates for different log sizes.