Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial PEP 740 documentation #16398

Merged
merged 56 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
9390173
initial attestations user docs
woodruffw Jun 6, 2024
01ee51a
more background, use preview
woodruffw Jun 6, 2024
e4cd67f
docs: more improvements
woodruffw Jun 10, 2024
a53df03
docs: attestation internals
woodruffw Jun 12, 2024
8a69bed
Merge branch 'main' into ww/attestations-docs
woodruffw Jun 12, 2024
18f7f25
Update docs/user/attestations/internals.md
woodruffw Jun 14, 2024
18adc03
publish/v1: clarify the signing target
woodruffw Jun 14, 2024
67e308c
Merge branch 'main' into ww/attestations-docs
woodruffw Jun 14, 2024
6220f33
Apply suggestions from code review
woodruffw Jun 14, 2024
3d82765
Merge branch 'main' into ww/attestations-docs
woodruffw Jun 17, 2024
647307b
v1: be explicit about payload
woodruffw Jun 20, 2024
9cb9d43
Merge branch 'main' into ww/attestations-docs
woodruffw Jun 21, 2024
0c38630
attestations: avoid "index attestations"
woodruffw Jun 21, 2024
8c8ac18
attestations/internals: remove another confusing phrase
woodruffw Jun 21, 2024
8bd8d10
Merge branch 'main' into ww/attestations-docs
woodruffw Jun 24, 2024
d243656
Merge branch 'main' into ww/attestations-docs
woodruffw Jul 2, 2024
5e3da1b
Merge branch 'main' into ww/attestations-docs
woodruffw Jul 12, 2024
56a8f29
Apply suggestions from code review
woodruffw Jul 12, 2024
2f26c08
docs: move internals doc to dev-docs
woodruffw Jul 12, 2024
42ad14b
dev: fix backticks
woodruffw Jul 12, 2024
23fdb5f
lintage, add note about trust
woodruffw Jul 13, 2024
012b2c6
Merge branch 'main' into ww/attestations-docs
woodruffw Jul 13, 2024
96e0d01
docs/dev: add callout for user docs
woodruffw Jul 13, 2024
52b004c
Update attestation-internals.rst
woodruffw Jul 17, 2024
a0bdd34
Update attestation-internals.rst
woodruffw Jul 18, 2024
1fbb3e0
Merge branch 'main' into ww/attestations-docs
woodruffw Jul 18, 2024
9de4a8d
Merge branch 'main' into ww/attestations-docs
woodruffw Jul 18, 2024
9dafec3
Merge branch 'main' into ww/attestations-docs
woodruffw Jul 23, 2024
a087dd9
Merge remote-tracking branch 'upstream/main' into ww/attestations-docs
woodruffw Jul 29, 2024
be5cd1a
Merge remote-tracking branch 'upstream/main' into ww/attestations-docs
woodruffw Aug 5, 2024
095987d
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Aug 7, 2024
24ca75a
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Aug 12, 2024
4624014
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Aug 21, 2024
583dfe1
tweak index attestations warning
woodruffw Aug 21, 2024
0e78ae0
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Sep 3, 2024
4de896a
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Sep 27, 2024
86cb0f9
docs: more PEP 740 docs, begin migrating user API docs
woodruffw Sep 27, 2024
15e1fbf
docs: integrity API, details
woodruffw Sep 27, 2024
c995260
api/integrity: fill in example
woodruffw Sep 27, 2024
3c8d7d8
document status code
woodruffw Sep 27, 2024
6ec51e0
docs/dev: add note about api docs migration
woodruffw Sep 30, 2024
dee1102
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Sep 30, 2024
42755c1
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Oct 21, 2024
2f3ee23
Merge branch 'main' into ww/attestation-docs-bump
woodruffw Nov 4, 2024
60cb6b4
Apply suggestions from code review
woodruffw Nov 6, 2024
877751b
api/integrity: avoid weird formatting
woodruffw Nov 6, 2024
2dd3fa3
Apply suggestions from code review
woodruffw Nov 6, 2024
c36d5f4
docs: link to #17001
woodruffw Nov 6, 2024
746463a
docs/dev: use sampleproject for attestation docs
woodruffw Nov 6, 2024
90a466b
dev-docs: more attestation internals to security/
woodruffw Nov 6, 2024
8b7719e
dev-docs: remove old index ref
woodruffw Nov 6, 2024
a3c7d6d
dev-docs: fix two more broken refs
woodruffw Nov 6, 2024
3263704
user-docs: use a real provenance example
woodruffw Nov 6, 2024
acbfd42
remove incorrect header
woodruffw Nov 7, 2024
d00da2a
make toctree placement less confusing
woodruffw Nov 7, 2024
594a7d1
Merge branch 'main' into ww/attestation-docs-bump
di Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/dev/api-reference/index.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
API reference
=============

.. note::

API documentation is being moved to PyPI's
`user documentation site <https://docs.pypi.org/api/>`_.

Please see `issue #16541 <https://github.com/pypi/warehouse/issues/16541>`_
for more information and status updates.

Warehouse has several API endpoints. See :doc:`../application` for the
parts of Warehouse that generate them.

Expand Down
5 changes: 4 additions & 1 deletion docs/dev/api-reference/legacy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ legacy PyPI upload API. This is the endpoint that tools such as `twine
<https://twine.readthedocs.io/>`_ use to `upload distributions to PyPI
<https://packaging.python.org/guides/distributing-packages-using-setuptools/#uploading-your-project-to-pypi>`_.

The upload api can be used to upload artifacts by sending a multipart/form-data
The upload API can be used to upload artifacts by sending a ``multipart/form-data``
POST request with the following fields:

- ``:action`` set to ``file_upload``
Expand All @@ -314,6 +314,9 @@ POST request with the following fields:
``source``
- ``metadata_version``, ``name`` and ``version`` set according to the
`Core metadata specifications`_
- ``attestations`` can be set to a JSON array of :pep:`740` attestation
objects. PyPI will reject the upload if it can't verify each of the
supplied.
- You can set any other field from the `Core metadata specifications`_.
All fields need to be renamed to lowercase and hyphens need to replaced
by underscores. So instead of "Description-Content-Type" the field must be
Expand Down
2 changes: 1 addition & 1 deletion docs/dev/development/submitting-patches.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ As you work on your patch, keep this in mind:
2.0.

If you believe you've identified a security issue in Warehouse, follow the
directions on the :doc:`security page </security>`.
directions on the :doc:`security page </security/index>`.

Code
----
Expand Down
2 changes: 1 addition & 1 deletion docs/dev/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Contents:
architecture
api-reference/index
ui-principles
security
security/index
translations
roadmap

Expand Down
348 changes: 348 additions & 0 deletions docs/dev/security/attestation-internals.rst

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion docs/dev/security.rst → docs/dev/security/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
Security
========

Contents:

.. toctree::
:maxdepth: 2

attestation-internals

Security policy
---------------
To read the most up to date version of our security policy, including
Expand All @@ -11,5 +18,6 @@ directions for submitting security vulnerabilities, please visit

Project and release activity details
------------------------------------
See :doc:`api-reference/feeds` for how to track new and updated releases on
See :doc:`/api-reference/feeds` for how to track new and updated releases on
PyPI.

11 changes: 10 additions & 1 deletion docs/mkdocs-user-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ markdown_extensions:
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: lower}}
slugify:
!!python/object/apply:pymdownx.slugs.slugify { kwds: { case: lower } }
- tables
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
Expand Down Expand Up @@ -71,4 +72,12 @@ nav:
- "trusted-publishers/security-model.md"
- "trusted-publishers/troubleshooting.md"
- "trusted-publishers/internals.md"
- "Digital Attestations":
- "attestations/index.md"
- "attestations/producing-attestations.md"
- "attestations/consuming-attestations.md"
- "attestations/publish/v1.md"
- "project_metadata.md"
- "API Reference":
- "api/index.md"
- "api/integrity.md"
52 changes: 52 additions & 0 deletions docs/user/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Introduction

<!--[[ preview('user-api-docs') ]]-->

PyPI has several API endpoints, each of which is referenced in the table
of contents for this hierarchy.

## API policies

Please be aware of these PyPI API policies:

### Caching

All API requests are cached. Requests to the JSON, RSS or Legacy APIs are
cached by our CDN provider. You can determine if you've hit the cache based on
the ``X-Cache`` and ``X-Cache-Hits`` headers in the response.

Requests to the JSON, RSS and Legacy APIs also provide an ``ETag`` header. If
you're making a lot of repeated requests, ensure your API consumer will respect
this header to determine whether to actually repeat a request or not.

The XML-RPC API does not have the ability to indicate cached responses.

### Rate limiting

Due to the heavy caching and CDN use, there is currently no rate limiting of
PyPI APIs at the edge. The XML-RPC API may be rate limited if usage is causing
degradation of service.

In addition, PyPI reserves the right to temporarily or permanently prohibit a
consumer based on irresponsible activity.

If you plan to make a lot of requests to a PyPI API, adhere to these
suggestions:

* Set your consumer's ``User-Agent`` header to uniquely identify your requests.
Adding your contact information to this value would be helpful as well.
* Try not to make a lot of requests (thousands) in a short amount of time
(minutes). Generally PyPI can handle it, but it's preferred to make requests
in serial over a longer amount of time if possible.
* If your consumer is actually an organization or service that will be
downloading a lot of packages from PyPI, consider `using your own index
mirror or cache
<https://packaging.python.org/guides/index-mirrors-and-caches/>`_.

### API Preference

For periodically checking for new packages or updates to existing packages,
use our RSS feeds.

No new integrations should use the XML-RPC APIs as they are planned for
deprecation. Existing consumers should migrate to JSON/RSS/Legacy APIs.
122 changes: 122 additions & 0 deletions docs/user/api/integrity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Integrity API

<!--[[ preview('user-api-docs') ]]-->

The Integrity API provides access to PyPI's implementation of [PEP 740].

## Concepts

The concepts and objects in the Integrity API closely mirror [PEP 740]:

* **Attestation objects** encapsulate a single "attestation" for a single file,
such as a [publish attestation] or [SLSA Provenance].

* **Provenance objects** encapsulate *one or more* attestations for a given
file, bundling them with the *identity* that produced them.

The Integrity API deals in provenance objects; users should extract and verify
individual attestations from a file's provenance, as appropriate.

## Routes

### Get provenance for file

Route: `GET /integrity/<project>/<version>/<filename>/provenance`

Get the provenance object for the given `<filename>`.

This endpoint is currently only available as JSON.

Example JSON request (default if no `Accept` header is passed):

```http
GET /integrity/sampleproject/4.0.0/sampleproject-4.0.0.tar.gz/provenance HTTP/1.1
Host: pypi.org
Accept: application/vnd.pypi.integrity.v1+json
```

??? note "Example JSON response"

This is an example response, demonstrating a provenance object containing
one attestation and its Trusted Publishing identity.
di marked this conversation as resolved.
Show resolved Hide resolved

```json
{
"attestation_bundles": [
{
"attestations": [
{
"envelope": {
"signature": "MEUCIQD1JCA8lWR9na44+zY2tr13sEuMCIu+FLS6eDkwESP5KgIgQDNG+eA5PiLSvVd+0AJn3Nk1V3CpRjRoz59L/MMTxyM=",
"statement": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoic2FtcGxlcHJvamVjdC00LjAuMC50YXIuZ3oiLCJkaWdlc3QiOnsic2hhMjU2IjoiMGFjZTc5ODBmODJjNTgxNWVkZTRjZDdiZjlmNjY5MzY4NGNlYzJhZTQ3YjliN2FkZTlhZGQ1MzNiODYyN2M2YiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2RvY3MucHlwaS5vcmcvYXR0ZXN0YXRpb25zL3B1Ymxpc2gvdjEiLCJwcmVkaWNhdGUiOm51bGx9"
},
"verification_material": {
"certificate": "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",
"transparency_entries": [
{
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiZHNzZSIsInNwZWMiOnsiZW52ZWxvcGVIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiOTNlMWYzNjRjODYwZWQ3MzI1MWYzYjI2YTU0YTM5NzFiZmZmZWYwNGU5MGNhNDgyNGU2YjhlMDJhMWIxMTVjMiJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6Ijk1YTdkMGM3ZmVhZWQ1NDA5NDJlZGZlNzBhZjlkM2JiNjNiNjNlODgwZDJkN2ExYzYzZmQ4NDI0YTU2YjQ1YmMifSwic2lnbmF0dXJlcyI6W3sic2lnbmF0dXJlIjoiTUVVQ0lRRDFKQ0E4bFdSOW5hNDQrelkydHIxM3NFdU1DSXUrRkxTNmVEa3dFU1A1S2dJZ1FETkcrZUE1UGlMU3ZWZCswQUpuM05rMVYzQ3BSalJvejU5TC9NTVR4eU09IiwidmVyaWZpZXIiOiJMUzB0TFMxQ1JVZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VkdlZFTkRRbWxwWjBGM1NVSkJaMGxVUm1GcEsxQkVTMkZyTVhoQk1VaE1jVEJ0YzJ0eGFFUldOWHBCUzBKblozRm9hMnBQVUZGUlJFRjZRVE1LVFZKVmQwVjNXVVJXVVZGTFJYZDRlbUZYWkhwa1J6bDVXbE0xYTFwWVdYaElha0ZqUW1kT1ZrSkJUVlJHV0U1d1dqTk9NR0l6U214TVYyeDFaRWRXZVFwaVYxWnJZVmRHTUZwVVFXVkdkekI1VGtSRmVFMUVXWGxOYWswelRVUmtZVVozTUhsT1JFVjRUVVJaZVUxcVVUTk5SR1JoVFVGQmQxZFVRVlJDWjJOeENtaHJhazlRVVVsQ1FtZG5jV2hyYWs5UVVVMUNRbmRPUTBGQlVtSjRNVVp6WlRKTWJqQXdUMjQxWVVaaFRDdHNTRTVIUmxsTVlYRmxTMFJrZFhCc1drUUtVRXBUSzNjeVVHcFpaazVRVERCbkwyNDBjMFJYUlZGR1dtWjVTVVY0UlZkTGRXeGFNa2RMVG5wQll6QXJVMjFWYnpSSlJsTkVRME5DVlZGM1JHZFpSQXBXVWpCUVFWRklMMEpCVVVSQloyVkJUVUpOUjBFeFZXUktVVkZOVFVGdlIwTkRjMGRCVVZWR1FuZE5SRTFDTUVkQk1WVmtSR2RSVjBKQ1ZDOTFVMFZKQ2xodFVYcDFVbXR3Y0ZkWWNsUkxWbXRtV2taS1lucEJaa0puVGxaSVUwMUZSMFJCVjJkQ1ZHWXdLMjVRVm1sUlVteDJiVzh5VDJ0dlZtRk1SMHhvYUdzS1VIcENhRUpuVGxaSVVrVkNRV1k0UlZaNlFsWm9iRTV2WkVoU2QyTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJZMGhzZDFsVE9YcFpWekYzWWtkV2R3cGpiVGx4V2xkT01FeDVOVzVoV0ZKdlpGZEpkbVF5T1hsaE1scHpZak5rZWt3elNteGlSMVpvWXpKVmRXVlhNWE5SU0Vwc1dtNU5kbUZIVm1oYVNFMTJDbUpYUm5CaWFrRTFRbWR2Y2tKblJVVkJXVTh2VFVGRlFrSkRkRzlrU0ZKM1kzcHZka3d6VW5aaE1sWjFURzFHYW1SSGJIWmliazExV2pKc01HRklWbWtLWkZoT2JHTnRUblppYmxKc1ltNVJkVmt5T1hSTlFrbEhRMmx6UjBGUlVVSm5OemgzUVZGSlJVSklRakZqTW1kM1RtZFpTMHQzV1VKQ1FVZEVkbnBCUWdwQmQxRnZUbXBKZUZwVVVUVk9lbEpxV1ZSSk1Wa3lWVEZOZWtVelRucE9hMXBYV1RGUFJGcHBXVlJPYkZwRWFHeE9lazB5V1dwT2JWbDZRVlpDWjI5eUNrSm5SVVZCV1U4dlRVRkZSVUpCWkZOYVYzaHNXVmhPYkUxRFFVZERhWE5IUVZGUlFtYzNPSGRCVVZWRlJXNUNOV05IUlhaak1rWjBZMGQ0YkdOSVNuWUtZVzFXYW1SRVFXUkNaMjl5UW1kRlJVRlpUeTlOUVVWSFFrRTVlVnBYV25wTU1taHNXVmRTZWt3eU1XaGhWelIzVDNkWlMwdDNXVUpDUVVkRWRucEJRZ3BEUVZGMFJFTjBiMlJJVW5kamVtOTJURE5TZG1FeVZuVk1iVVpxWkVkc2RtSnVUWFZhTW13d1lVaFdhV1JZVG14amJVNTJZbTVTYkdKdVVYVlpNamwwQ2sxSFRVZERhWE5IUVZGUlFtYzNPSGRCVVd0RlZsRjRWR0ZJVWpCalNFMDJUSGs1Ym1GWVVtOWtWMGwxV1RJNWRFd3pRalZqUjBWMll6SkdkR05IZUd3S1kwaEtkbUZ0Vm1wa1F6aDFXakpzTUdGSVZtbE1NMlIyWTIxMGJXSkhPVE5qZVRsNVdsZDRiRmxZVG14TWJteDBZa1ZDZVZwWFducE1NbWhzV1ZkU2VncE1NakZvWVZjMGQwOUJXVXRMZDFsQ1FrRkhSSFo2UVVKRFoxRnhSRU5uTWsxcVJteE9SR3N6VGtkT2FFMXFWbXBhVkZWNlRWUmpNMDB5VW14YWFsVTBDazV0U21oTk1sWnJUMGRWTTAxNldtbE5NbHBxVFVJd1IwTnBjMGRCVVZGQ1p6YzRkMEZSYzBWRWQzZE9XakpzTUdGSVZtbE1WMmgyWXpOU2JGcEVRVEVLUW1kdmNrSm5SVVZCV1U4dlRVRkZUVUpEWTAxS1YyZ3daRWhDZWs5cE9IWmFNbXd3WVVoV2FVeHRUblppVXpsM1pWaENhRXd6VG1oaVdFSnpXbGhDZVFwaU1uQnNXVE5SZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5NazFxUm14T1JHc3pUa2RPYUUxcVZtcGFWRlY2VFZSak0wMHlVbXhhYWxVMENrNXRTbWhOTWxaclQwZFZNMDE2V21sTk1scHFUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c5YVYwWnJZM2s1ZEZsWGJIVUtUVUpuUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEWjNkSlRWUlJORTlVYXpGUFZGbDNTbmRaUzB0M1dVSkNRVWRFZG5wQlFrVkJVVnBFUW1SdlpFaFNkd3BqZW05MlRESmtjR1JIYURGWmFUVnFZakl3ZG1OSWJIZFpWRUZYUW1kdmNrSm5SVVZCV1U4dlRVRkZVa0pCWjAxQ2Fsa3dUbnBCZVU1VVFtcENaMjl5Q2tKblJVVkJXVTh2VFVGRlUwSkdWVTFWTW1nd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemwzWlZoQ2FFd3pUbWhpV0VKeldsaENlV0l5Y0d3S1dUTlJka3h0WkhCa1IyZ3hXV2s1TTJJelNuSmFiWGgyWkROTmRtTnRWbk5hVjBaNldsTTFOV0pYZUVGamJWWnRZM2s1YjFwWFJtdGplVGwwV1Zkc2RRcE5SR2RIUTJselIwRlJVVUpuTnpoM1FWSk5SVXRuZDI5T2FrbDRXbFJSTlU1NlVtcFpWRWt4V1RKVk1VMTZSVE5PZWs1cldsZFpNVTlFV21sWlZFNXNDbHBFYUd4T2VrMHlXV3BPYlZsNlFWVkNaMjl5UW1kRlJVRlpUeTlOUVVWVlFrRlpUVUpJUWpGak1tZDNWMUZaUzB0M1dVSkNRVWRFZG5wQlFrWlJVa3dLUkVWc2IyUklVbmRqZW05MlRESmtjR1JIYURGWmFUVnFZakl3ZG1OSWJIZFpVemw2V1ZjeGQySkhWbmRqYlRseFdsZE9NRXd5Um1wa1IyeDJZbTVOZGdwamJsWjFZM2s0ZUUxVVkzaE5la0Y2VDBSck5FMVRPV2hrU0ZKc1lsaENNR041T0hoTlFsbEhRMmx6UjBGUlVVSm5OemgzUVZKWlJVTkJkMGRqU0ZacENtSkhiR3BOU1VkTFFtZHZja0puUlVWQlpGbzFRV2RSUTBKSWQwVmxaMEkwUVVoWlFUTlVNSGRoYzJKSVJWUktha2RTTkdOdFYyTXpRWEZLUzFoeWFtVUtVRXN6TDJnMGNIbG5Remh3TjI4MFFVRkJSMVJCTlM5WU5VRkJRVUpCVFVGU2VrSkdRV2xCTm01WlN6QkhlSEZXZWtwMWRISnFjbGxCTVdKQlNVdElWUXBxUjNKelNFMU1jazlLVkZSRlZXbEZVa0ZKYUVGS1dtOTBRVlJ1VTNkc1MzUTNRek5hZDJoNE0yWmpVM0pvUjJaUFlXdFViRTB5ZHlzNGNXMXNkR05xQ2sxQmIwZERRM0ZIVTAwME9VSkJUVVJCTW1OQlRVZFJRMDFDSzJsc2MxQm5lVFI1YmxWSE9VZDBjVVJGUW5GWE9DdGFjV3BZTmt4d2RYaFJjV3BEY2pjS2N6UjVkSGwwTW5Cd1JtUm5hbkpIY2tjeFJGazBibE5hZEZGSmQySnNjbWR4T1hRNWFYcEJUVlJyU21WeGFGRkNjekpQVldsNVNVcGFhWEJqWlVRMWRncEJRVVV2VG1ablpDODVkVXN3VFZwQlNFWnpUR2RoYkhGUFFtdzRDaTB0TFMwdFJVNUVJRU5GVWxSSlJrbERRVlJGTFMwdExTMEsifV19fQ==",
"inclusionPromise": {
"signedEntryTimestamp": "MEQCIGzFZon9/joNsiQOL1uoIP/gtz7/A6eAB+50oX3M0CBaAiAZmLVxcgknlWls6R1FswJWCHY0vkwQ/jE5dSkcY43jWA=="
},
"inclusionProof": {
"checkpoint": {
"envelope": "rekor.sigstore.dev - 1193050959916656506\n25232879\nQrnMowJnGj9hZkL1UOvkg7w+KuG27PEDcsdaEqCtoDM=\n\n— rekor.sigstore.dev wNI9ajBFAiEAshgj30XTIU+L6UyYL0yzLXJbLFmxPEc8ZRmS1R3N1sQCIFCjFEqe9J+Et9sWzJp6SE3p7Eh/+97zON7mwX6unCem\n"
},
"hashes": [
"Bc4heeKQhKCr6/ZtuEHmAyp8AzvP4N1ROusEacAmfFQ=",
"ZTeyp2wk6H1Bgz3SZOqQWoQvCmkiltfFstDiy1WaR9Y=",
"vnHPC5XIhbYQib86Hi6M4OaEOFGFMlOip8+5mxZd8cs=",
"BEONTVFois+c47/YA7vzwZG7fbNLBkVLz1hUM/WMb1k=",
"PWqRmPYAwa1fq6R1qSrYlOxCtiKnFZq9hnNt7XwCIA8=",
"KHxYP0XNSf1yKjp+xY/5Kkckw0Yweyjx9Z6qn2+pnZM=",
"8/b9kmTAbALhl4EaKIH4uMXhES9ILB0XQkuH44FltJY=",
"mXfX9NDkaWje6HpniWis2CBELUGjv8LiW2jeMOclCs0=",
"jRPOva2IEma7ZE7mPN3xHtEnXtMF/HNvrmbC5TKTy14=",
"s8vUdxeRlxXWTCMdSLhiSzRiYM3eGsVvrm+5HWkTNBc=",
"4lUF0YOu9XkIDXKXA0wMSzd6VeDY3TZAgmoOeWmS2+Y=",
"gf+9m552B3PnkWnO0o4KdVvjcT3WVHLrCbf1DoVYKFw="
],
"logIndex": "25232877",
"rootHash": "QrnMowJnGj9hZkL1UOvkg7w+KuG27PEDcsdaEqCtoDM=",
"treeSize": "25232879"
},
"integratedTime": "1730932627",
"kindVersion": {
"kind": "dsse",
"version": "0.0.1"
},
"logId": {
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
},
"logIndex": "147137139"
}
]
},
"version": 1
}
],
"publisher": {
"claims": null,
"environment": "",
"kind": "GitHub",
"repository": "pypa/sampleproject",
"workflow": "release.yml"
}
}
],
"version": 1
}
```

#### Status codes

* `200 OK` - no error, provenance is available
* `403 Forbidden` - access is temporarily disabled by the PyPI administrators
* `404 Not Found` - file has no provenance
* `406 Not Acceptable` - `Accept:` header not recognized

[PEP 740]: https://peps.python.org/pep-0740/

[publish attestation]: /attestations/publish/v1

[SLSA Provenance]: https://slsa.dev/spec/v1.0/provenance
10 changes: 10 additions & 0 deletions docs/user/attestations/consuming-attestations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Consuming attestations

<!--[[ preview('index-attestations') ]]-->

PyPI makes a file's attestations available via the simple index (HTML)
and simple JSON APIs.

For a full API reference, see the [Integrity API documentation].

[Integrity API documentation]: /api/integrity/
47 changes: 47 additions & 0 deletions docs/user/attestations/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: Introduction
---

<!--[[ preview('index-attestations') ]]-->

These pages document PyPI's implementation of digital attestations ([PEP 740]),
including in-toto attestation predicates specific to PyPI itself.

## Quick background

*Digital attestations* enable package maintainers as well as third parties (such
as the index itself, external auditors, etc.) to *cryptographically sign*
for uploaded packages.

These signatures bind each release distribution (such as an individual sdist or
wheel) to a strong cryptographic digest of its contents, allowing both PyPI
and downstream users to verify that a particular package was attested to by
a particular identity (such as a GitHub Actions workflow).

These attestations can take multiple forms, including [publish attestations]
for publicly verifiable proof that a package was published via a specific
[Trusted Publisher], or more general [SLSA Provenance] attesting to a package's
original source location.

## Supported attestations

PyPI uses the [in-toto Attestation Framework] for the attestations it accepts.

Currently, PyPI allows the following attestation predicates:

* [SLSA Provenance]
* [PyPI Publish]

[in-toto Attestation Framework]: https://github.com/in-toto/attestation/blob/main/spec/README.md

[PEP 740]: https://peps.python.org/pep-0740/

[PyPI Publish]: /attestations/publish/v1/

[publish attestations]: /attestations/publish/v1/

[Trusted Publisher]: /trusted-publishers/

[SLSA Provenance]: https://slsa.dev/spec/v1.0/provenance


Loading