The Python Package Index (PyPI) is the first package registry to implement this style guide’s recommendations, following the highest UI requirements (Level AAA). This work included:
The implementation was tracked on the Warehouse issue tracker and publicized on the PyPI blog.
This page documents:
Most recommendations in this style guide assume a package has a single, package-level attestation. PyPI does not work that way: a single release is a collection of files, with each file carrying (or not carrying) its own attestation. A release can therefore be in a mixed state (e.g., some files fully attested, others missing attestations) with no single “the package is attested” status to display.
This meant PyPI could not simply drop the style guide’s attestation component onto a project page. The team needed to decide what to show at the release level (a summary), what to show at the file level (the detail), and how to handle discrepancies between the two.
PyPI also needed to decide how to handle edge cases and warning states that were not explicitly documented in the style guide, including:
In all cases, there could be legitimate explanations for these anomalies (e.g., a maintainer has migrated publishing or code-hosting platforms). However, these patterns are also strong indicators of a potential compromise. Communicating this requires a careful balance: warning users to act with appropriate caution without unfairly penalizing or shaming maintainers who make legitimate workflow changes.
Beyond attestations, PyPI already presented other security signals that needed to be considered in the redesign:
Metadata verification: PyPI checks select maintainer-provided metadata during upload, historically grouping it into “Verified details” and “Unverified details” sections in the sidebar. However, this labeling was ambiguous in scope and sometimes led users to believe the entire release (rather than just its metadata) had been validated.
Late-uploaded distribution files: PyPI previously allowed maintainers to upload new distribution files indefinitely after a release date. Although PyPI introduced a 14-day window for adding new files in July 2026, the UI still needed to highlight historical “late files”, particularly to help contextualize attestation anomalies.
We created, refined, and built new designs as clickable prototypes. This included:
The designs were then evaluated through user research, including:
The survey asked respondents to rank metadata (including provenance) by importance when evaluating a package’s trustworthiness and suitability.
The interviews asked users to interact with clickable prototypes, testing six provenance states:
Key findings:
User feedback was integrated into the final designs before implementation. For example, we dropped the per-file anomalies design: participants found comparisons between files within a release confusing, and comparisons between releases more useful. As a result, provenance warnings are summarized at the release level: even “Inconsistent provenance”, which compares files within a release, is presented as a single release-level warning, with files grouped by repository and configuration.
The following screenshots document the PyPI implementation.
When a release has no provenance:

When users select the security tab, they see:
A description of provenance and attestations:
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
A “No provenance found” alert:

This approach introduces users to the concepts of provenance and attestations without penalizing maintainers by displaying a negative “No provenance” status on the main tab.
When a release contains provenance metadata, it is surfaced across several parts of the UI.
On the project description tab:

On the security tab:


The attestations have been adapted for each attestation type:
On the files tab:

The attestation block is also included on the file detail page (accessed via the “Details” button).
When an anomaly is detected in the release’s provenance, it is surfaced across the interface:
When only some files carry attestations, an “Incomplete provenance” warning appears in the release status bar and the sidebar’s provenance panel, linking to further details:

On the security tab, an alert explains how many files were uploaded without provenance metadata, accompanied by a bar chart breaking down the release’s files:

On the files tab, an alert is displayed, with individual files marked as either “With provenance” or “Without provenance”:

When files within the same release originate from differing repositories or configurations, an “Inconsistent provenance” alert is surfaced across the top bar and sidebar panel:

The security tab outlines the distinct repositories and configurations detected across the artifacts, grouping files by the repository and configuration that produced them:

On the files tab, an alert notes that the release’s files originate from different repositories or configurations:

When provenance has been lost between releases2, the UI displays a “Loss of provenance” alert in the top bar and sidebar:

On the security tab, an alert explains that a previous release had provenance metadata while the current one does not, and includes a release comparison table:

On the files tab, an alert is added that links users to the security tab for more information:

When the publishing repository or configuration changes between releases, a “Change of provenance” warning is surfaced across the release status bar and sidebar:

On the security tab, an alert explains that the repository and configuration that created this release differ from a previous release, accompanied by a diff comparison:

On the files tab, an alert is added that links users to the security tab for more information:

When a file is uploaded more than 14 days after the first file in a release, a “File added late” warning is surfaced in the release status bar, as well as on the files tab and file detail page. On the security tab, an “Upload timing” section is added to provide more context. Because PyPI now rejects new files after 14 days, this warning only appears on historical releases.

When a release has both late-file and provenance anomalies, the release status bar shows only the provenance warning. On the files tab and file detail page, the warnings are consolidated into a single composite alert for improved usability (e.g., “Loss of provenance, with files added late”).
To support the UI changes, we updated the user documentation, following this guide’s documentation recommendations:
/help page was migrated into structured, role-specific user documentationUntil these terms become industry-standard knowledge, registries should define them clearly. On PyPI, we added this description to the security tab, which links directly to the updated documentation:
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
As documented in the Level AA recommendations, we found that users quickly jump to conclusions about these indicators, sometimes assuming that a positive security badge means a package is 100% secure. Two of six interview participants assumed that “verified” meant the PyPI team had manually audited the release’s source code.
If you use “verified”, checkmarks, or green badges, be careful to scope them explicitly. For example, we labeled verified metadata as:
Data verified by PyPI on <date>
This clarifies that the data has been verified, not the entire release or codebase.
We found that prioritizing security information above all else is not what users wanted; they looked for decision-relevant facts first, whether security-related or not. This finding is consistent with other recommendations in this style guide.
Users typically scan web pages rather than read every piece of text in detail. We found that warnings prompt users to pause when they:
All designs and prototypes were shared on the Warehouse issue tracker for public feedback. We also staged each major change to TestPyPI, directing users to an issue where they could provide feedback. This process surfaced edge-case bugs and generated actionable feedback that we addressed before closing out the project.
Designing in the open and releasing changes in phases also helped users adapt: previewing upcoming changes and providing early feedback fostered a sense of involvement and community ownership.
Back to: Style guide overview
The release status bar is also used to display other critical states, such as when a project or release has been quarantined by PyPI administrators. In this scenario, quarantine status takes precedence, and provenance warnings are suppressed from this top bar. ↩
A release displays “Loss of provenance” if none of its files have attestations, but a prior release created within the preceding 14 days did. We chose a time-based window rather than a release count to prevent an attacker from flooding a project with releases to suppress the warning. ↩