Skip to content

Commit ac0dee9

Browse files
woodruffwfacutuescadi
authored
Initial PEP 740 documentation (#16398)
* initial attestations user docs Signed-off-by: William Woodruff <[email protected]> * more background, use preview Signed-off-by: William Woodruff <[email protected]> * docs: more improvements Signed-off-by: William Woodruff <[email protected]> * docs: attestation internals Signed-off-by: William Woodruff <[email protected]> * Update docs/user/attestations/internals.md Co-authored-by: Facundo Tuesca <[email protected]> * publish/v1: clarify the signing target Signed-off-by: William Woodruff <[email protected]> * Apply suggestions from code review Co-authored-by: Facundo Tuesca <[email protected]> * v1: be explicit about payload Signed-off-by: William Woodruff <[email protected]> * attestations: avoid "index attestations" Signed-off-by: William Woodruff <[email protected]> * attestations/internals: remove another confusing phrase Signed-off-by: William Woodruff <[email protected]> * Apply suggestions from code review Co-authored-by: Dustin Ingram <[email protected]> * docs: move internals doc to dev-docs Signed-off-by: William Woodruff <[email protected]> * dev: fix backticks Signed-off-by: William Woodruff <[email protected]> * lintage, add note about trust Signed-off-by: William Woodruff <[email protected]> * docs/dev: add callout for user docs Signed-off-by: William Woodruff <[email protected]> * Update attestation-internals.rst Co-authored-by: Dustin Ingram <[email protected]> * Update attestation-internals.rst Co-authored-by: Dustin Ingram <[email protected]> * tweak index attestations warning Signed-off-by: William Woodruff <[email protected]> * docs: more PEP 740 docs, begin migrating user API docs Signed-off-by: William Woodruff <[email protected]> * docs: integrity API, details Signed-off-by: William Woodruff <[email protected]> * api/integrity: fill in example Signed-off-by: William Woodruff <[email protected]> * document status code Signed-off-by: William Woodruff <[email protected]> * docs/dev: add note about api docs migration Signed-off-by: William Woodruff <[email protected]> * Apply suggestions from code review Co-authored-by: Dustin Ingram <[email protected]> * api/integrity: avoid weird formatting Signed-off-by: William Woodruff <[email protected]> * Apply suggestions from code review Co-authored-by: Dustin Ingram <[email protected]> * docs: link to #17001 Signed-off-by: William Woodruff <[email protected]> * docs/dev: use sampleproject for attestation docs Signed-off-by: William Woodruff <[email protected]> * dev-docs: more attestation internals to security/ Signed-off-by: William Woodruff <[email protected]> * dev-docs: remove old index ref Signed-off-by: William Woodruff <[email protected]> * dev-docs: fix two more broken refs Signed-off-by: William Woodruff <[email protected]> * user-docs: use a real provenance example Signed-off-by: William Woodruff <[email protected]> * remove incorrect header Signed-off-by: William Woodruff <[email protected]> * make toctree placement less confusing Signed-off-by: William Woodruff <[email protected]> --------- Signed-off-by: William Woodruff <[email protected]> Co-authored-by: Facundo Tuesca <[email protected]> Co-authored-by: Dustin Ingram <[email protected]>
1 parent c2d911f commit ac0dee9

14 files changed

+831
-7
lines changed

Diff for: docs/dev/api-reference/index.rst

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
API reference
22
=============
33

4+
.. note::
5+
6+
API documentation is being moved to PyPI's
7+
`user documentation site <https://docs.pypi.org/api/>`_.
8+
9+
Please see `issue #16541 <https://github.com/pypi/warehouse/issues/16541>`_
10+
for more information and status updates.
11+
412
Warehouse has several API endpoints. See :doc:`../application` for the
513
parts of Warehouse that generate them.
614

Diff for: docs/dev/api-reference/legacy.rst

+4-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ legacy PyPI upload API. This is the endpoint that tools such as `twine
295295
<https://twine.readthedocs.io/>`_ use to `upload distributions to PyPI
296296
<https://packaging.python.org/guides/distributing-packages-using-setuptools/#uploading-your-project-to-pypi>`_.
297297

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

301301
- ``:action`` set to ``file_upload``
@@ -314,6 +314,9 @@ POST request with the following fields:
314314
``source``
315315
- ``metadata_version``, ``name`` and ``version`` set according to the
316316
`Core metadata specifications`_
317+
- ``attestations`` can be set to a JSON array of :pep:`740` attestation
318+
objects. PyPI will reject the upload if it can't verify each of the
319+
supplied.
317320
- You can set any other field from the `Core metadata specifications`_.
318321
All fields need to be renamed to lowercase and hyphens need to replaced
319322
by underscores. So instead of "Description-Content-Type" the field must be

Diff for: docs/dev/development/submitting-patches.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ As you work on your patch, keep this in mind:
1515
2.0.
1616

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

2020
Code
2121
----

Diff for: docs/dev/index.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Contents:
1111
architecture
1212
api-reference/index
1313
ui-principles
14-
security
14+
security/index
1515
translations
1616
roadmap
1717

Diff for: docs/dev/security/attestation-internals.rst

+348
Large diffs are not rendered by default.

Diff for: docs/dev/security.rst renamed to docs/dev/security/index.rst

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
Security
44
========
55

6+
Contents:
7+
8+
.. toctree::
9+
:maxdepth: 2
10+
11+
attestation-internals
12+
613
Security policy
714
---------------
815
To read the most up to date version of our security policy, including
@@ -11,5 +18,6 @@ directions for submitting security vulnerabilities, please visit
1118

1219
Project and release activity details
1320
------------------------------------
14-
See :doc:`api-reference/feeds` for how to track new and updated releases on
21+
See :doc:`/api-reference/feeds` for how to track new and updated releases on
1522
PyPI.
23+

Diff for: docs/mkdocs-user-docs.yml

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ markdown_extensions:
1616
- pymdownx.superfences
1717
- pymdownx.tabbed:
1818
alternate_style: true
19-
slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: lower}}
19+
slugify:
20+
!!python/object/apply:pymdownx.slugs.slugify { kwds: { case: lower } }
2021
- tables
2122
- pymdownx.emoji:
2223
emoji_index: !!python/name:material.extensions.emoji.twemoji
@@ -71,4 +72,12 @@ nav:
7172
- "trusted-publishers/security-model.md"
7273
- "trusted-publishers/troubleshooting.md"
7374
- "trusted-publishers/internals.md"
75+
- "Digital Attestations":
76+
- "attestations/index.md"
77+
- "attestations/producing-attestations.md"
78+
- "attestations/consuming-attestations.md"
79+
- "attestations/publish/v1.md"
7480
- "project_metadata.md"
81+
- "API Reference":
82+
- "api/index.md"
83+
- "api/integrity.md"

Diff for: docs/user/api/index.md

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Introduction
2+
3+
<!--[[ preview('user-api-docs') ]]-->
4+
5+
PyPI has several API endpoints, each of which is referenced in the table
6+
of contents for this hierarchy.
7+
8+
## API policies
9+
10+
Please be aware of these PyPI API policies:
11+
12+
### Caching
13+
14+
All API requests are cached. Requests to the JSON, RSS or Legacy APIs are
15+
cached by our CDN provider. You can determine if you've hit the cache based on
16+
the ``X-Cache`` and ``X-Cache-Hits`` headers in the response.
17+
18+
Requests to the JSON, RSS and Legacy APIs also provide an ``ETag`` header. If
19+
you're making a lot of repeated requests, ensure your API consumer will respect
20+
this header to determine whether to actually repeat a request or not.
21+
22+
The XML-RPC API does not have the ability to indicate cached responses.
23+
24+
### Rate limiting
25+
26+
Due to the heavy caching and CDN use, there is currently no rate limiting of
27+
PyPI APIs at the edge. The XML-RPC API may be rate limited if usage is causing
28+
degradation of service.
29+
30+
In addition, PyPI reserves the right to temporarily or permanently prohibit a
31+
consumer based on irresponsible activity.
32+
33+
If you plan to make a lot of requests to a PyPI API, adhere to these
34+
suggestions:
35+
36+
* Set your consumer's ``User-Agent`` header to uniquely identify your requests.
37+
Adding your contact information to this value would be helpful as well.
38+
* Try not to make a lot of requests (thousands) in a short amount of time
39+
(minutes). Generally PyPI can handle it, but it's preferred to make requests
40+
in serial over a longer amount of time if possible.
41+
* If your consumer is actually an organization or service that will be
42+
downloading a lot of packages from PyPI, consider `using your own index
43+
mirror or cache
44+
<https://packaging.python.org/guides/index-mirrors-and-caches/>`_.
45+
46+
### API Preference
47+
48+
For periodically checking for new packages or updates to existing packages,
49+
use our RSS feeds.
50+
51+
No new integrations should use the XML-RPC APIs as they are planned for
52+
deprecation. Existing consumers should migrate to JSON/RSS/Legacy APIs.

Diff for: docs/user/api/integrity.md

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Integrity API
2+
3+
<!--[[ preview('user-api-docs') ]]-->
4+
5+
The Integrity API provides access to PyPI's implementation of [PEP 740].
6+
7+
## Concepts
8+
9+
The concepts and objects in the Integrity API closely mirror [PEP 740]:
10+
11+
* **Attestation objects** encapsulate a single "attestation" for a single file,
12+
such as a [publish attestation] or [SLSA Provenance].
13+
14+
* **Provenance objects** encapsulate *one or more* attestations for a given
15+
file, bundling them with the *identity* that produced them.
16+
17+
The Integrity API deals in provenance objects; users should extract and verify
18+
individual attestations from a file's provenance, as appropriate.
19+
20+
## Routes
21+
22+
### Get provenance for file
23+
24+
Route: `GET /integrity/<project>/<version>/<filename>/provenance`
25+
26+
Get the provenance object for the given `<filename>`.
27+
28+
This endpoint is currently only available as JSON.
29+
30+
Example JSON request (default if no `Accept` header is passed):
31+
32+
```http
33+
GET /integrity/sampleproject/4.0.0/sampleproject-4.0.0.tar.gz/provenance HTTP/1.1
34+
Host: pypi.org
35+
Accept: application/vnd.pypi.integrity.v1+json
36+
```
37+
38+
??? note "Example JSON response"
39+
40+
This is an example response, demonstrating a provenance object containing
41+
one attestation and its Trusted Publishing identity.
42+
43+
```json
44+
{
45+
"attestation_bundles": [
46+
{
47+
"attestations": [
48+
{
49+
"envelope": {
50+
"signature": "MEUCIQD1JCA8lWR9na44+zY2tr13sEuMCIu+FLS6eDkwESP5KgIgQDNG+eA5PiLSvVd+0AJn3Nk1V3CpRjRoz59L/MMTxyM=",
51+
"statement": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoic2FtcGxlcHJvamVjdC00LjAuMC50YXIuZ3oiLCJkaWdlc3QiOnsic2hhMjU2IjoiMGFjZTc5ODBmODJjNTgxNWVkZTRjZDdiZjlmNjY5MzY4NGNlYzJhZTQ3YjliN2FkZTlhZGQ1MzNiODYyN2M2YiJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2RvY3MucHlwaS5vcmcvYXR0ZXN0YXRpb25zL3B1Ymxpc2gvdjEiLCJwcmVkaWNhdGUiOm51bGx9"
52+
},
53+
"verification_material": {
54+
"certificate": "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",
55+
"transparency_entries": [
56+
{
57+
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiZHNzZSIsInNwZWMiOnsiZW52ZWxvcGVIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiOTNlMWYzNjRjODYwZWQ3MzI1MWYzYjI2YTU0YTM5NzFiZmZmZWYwNGU5MGNhNDgyNGU2YjhlMDJhMWIxMTVjMiJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6Ijk1YTdkMGM3ZmVhZWQ1NDA5NDJlZGZlNzBhZjlkM2JiNjNiNjNlODgwZDJkN2ExYzYzZmQ4NDI0YTU2YjQ1YmMifSwic2lnbmF0dXJlcyI6W3sic2lnbmF0dXJlIjoiTUVVQ0lRRDFKQ0E4bFdSOW5hNDQrelkydHIxM3NFdU1DSXUrRkxTNmVEa3dFU1A1S2dJZ1FETkcrZUE1UGlMU3ZWZCswQUpuM05rMVYzQ3BSalJvejU5TC9NTVR4eU09IiwidmVyaWZpZXIiOiJMUzB0TFMxQ1JVZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VkdlZFTkRRbWxwWjBGM1NVSkJaMGxVUm1GcEsxQkVTMkZyTVhoQk1VaE1jVEJ0YzJ0eGFFUldOWHBCUzBKblozRm9hMnBQVUZGUlJFRjZRVE1LVFZKVmQwVjNXVVJXVVZGTFJYZDRlbUZYWkhwa1J6bDVXbE0xYTFwWVdYaElha0ZqUW1kT1ZrSkJUVlJHV0U1d1dqTk9NR0l6U214TVYyeDFaRWRXZVFwaVYxWnJZVmRHTUZwVVFXVkdkekI1VGtSRmVFMUVXWGxOYWswelRVUmtZVVozTUhsT1JFVjRUVVJaZVUxcVVUTk5SR1JoVFVGQmQxZFVRVlJDWjJOeENtaHJhazlRVVVsQ1FtZG5jV2hyYWs5UVVVMUNRbmRPUTBGQlVtSjRNVVp6WlRKTWJqQXdUMjQxWVVaaFRDdHNTRTVIUmxsTVlYRmxTMFJrZFhCc1drUUtVRXBUSzNjeVVHcFpaazVRVERCbkwyNDBjMFJYUlZGR1dtWjVTVVY0UlZkTGRXeGFNa2RMVG5wQll6QXJVMjFWYnpSSlJsTkVRME5DVlZGM1JHZFpSQXBXVWpCUVFWRklMMEpCVVVSQloyVkJUVUpOUjBFeFZXUktVVkZOVFVGdlIwTkRjMGRCVVZWR1FuZE5SRTFDTUVkQk1WVmtSR2RSVjBKQ1ZDOTFVMFZKQ2xodFVYcDFVbXR3Y0ZkWWNsUkxWbXRtV2taS1lucEJaa0puVGxaSVUwMUZSMFJCVjJkQ1ZHWXdLMjVRVm1sUlVteDJiVzh5VDJ0dlZtRk1SMHhvYUdzS1VIcENhRUpuVGxaSVVrVkNRV1k0UlZaNlFsWm9iRTV2WkVoU2QyTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJZMGhzZDFsVE9YcFpWekYzWWtkV2R3cGpiVGx4V2xkT01FeDVOVzVoV0ZKdlpGZEpkbVF5T1hsaE1scHpZak5rZWt3elNteGlSMVpvWXpKVmRXVlhNWE5SU0Vwc1dtNU5kbUZIVm1oYVNFMTJDbUpYUm5CaWFrRTFRbWR2Y2tKblJVVkJXVTh2VFVGRlFrSkRkRzlrU0ZKM1kzcHZka3d6VW5aaE1sWjFURzFHYW1SSGJIWmliazExV2pKc01HRklWbWtLWkZoT2JHTnRUblppYmxKc1ltNVJkVmt5T1hSTlFrbEhRMmx6UjBGUlVVSm5OemgzUVZGSlJVSklRakZqTW1kM1RtZFpTMHQzV1VKQ1FVZEVkbnBCUWdwQmQxRnZUbXBKZUZwVVVUVk9lbEpxV1ZSSk1Wa3lWVEZOZWtVelRucE9hMXBYV1RGUFJGcHBXVlJPYkZwRWFHeE9lazB5V1dwT2JWbDZRVlpDWjI5eUNrSm5SVVZCV1U4dlRVRkZSVUpCWkZOYVYzaHNXVmhPYkUxRFFVZERhWE5IUVZGUlFtYzNPSGRCVVZWRlJXNUNOV05IUlhaak1rWjBZMGQ0YkdOSVNuWUtZVzFXYW1SRVFXUkNaMjl5UW1kRlJVRlpUeTlOUVVWSFFrRTVlVnBYV25wTU1taHNXVmRTZWt3eU1XaGhWelIzVDNkWlMwdDNXVUpDUVVkRWRucEJRZ3BEUVZGMFJFTjBiMlJJVW5kamVtOTJURE5TZG1FeVZuVk1iVVpxWkVkc2RtSnVUWFZhTW13d1lVaFdhV1JZVG14amJVNTJZbTVTYkdKdVVYVlpNamwwQ2sxSFRVZERhWE5IUVZGUlFtYzNPSGRCVVd0RlZsRjRWR0ZJVWpCalNFMDJUSGs1Ym1GWVVtOWtWMGwxV1RJNWRFd3pRalZqUjBWMll6SkdkR05IZUd3S1kwaEtkbUZ0Vm1wa1F6aDFXakpzTUdGSVZtbE1NMlIyWTIxMGJXSkhPVE5qZVRsNVdsZDRiRmxZVG14TWJteDBZa1ZDZVZwWFducE1NbWhzV1ZkU2VncE1NakZvWVZjMGQwOUJXVXRMZDFsQ1FrRkhSSFo2UVVKRFoxRnhSRU5uTWsxcVJteE9SR3N6VGtkT2FFMXFWbXBhVkZWNlRWUmpNMDB5VW14YWFsVTBDazV0U21oTk1sWnJUMGRWTTAxNldtbE5NbHBxVFVJd1IwTnBjMGRCVVZGQ1p6YzRkMEZSYzBWRWQzZE9XakpzTUdGSVZtbE1WMmgyWXpOU2JGcEVRVEVLUW1kdmNrSm5SVVZCV1U4dlRVRkZUVUpEWTAxS1YyZ3daRWhDZWs5cE9IWmFNbXd3WVVoV2FVeHRUblppVXpsM1pWaENhRXd6VG1oaVdFSnpXbGhDZVFwaU1uQnNXVE5SZDA5QldVdExkMWxDUWtGSFJIWjZRVUpFVVZGeFJFTm5NazFxUm14T1JHc3pUa2RPYUUxcVZtcGFWRlY2VFZSak0wMHlVbXhhYWxVMENrNXRTbWhOTWxaclQwZFZNMDE2V21sTk1scHFUVUk0UjBOcGMwZEJVVkZDWnpjNGQwRlJORVZGVVhkUVkyMVdiV041T1c5YVYwWnJZM2s1ZEZsWGJIVUtUVUpuUjBOcGMwZEJVVkZDWnpjNGQwRlJPRVZEWjNkSlRWUlJORTlVYXpGUFZGbDNTbmRaUzB0M1dVSkNRVWRFZG5wQlFrVkJVVnBFUW1SdlpFaFNkd3BqZW05MlRESmtjR1JIYURGWmFUVnFZakl3ZG1OSWJIZFpWRUZYUW1kdmNrSm5SVVZCV1U4dlRVRkZVa0pCWjAxQ2Fsa3dUbnBCZVU1VVFtcENaMjl5Q2tKblJVVkJXVTh2VFVGRlUwSkdWVTFWTW1nd1pFaENlazlwT0haYU1td3dZVWhXYVV4dFRuWmlVemwzWlZoQ2FFd3pUbWhpV0VKeldsaENlV0l5Y0d3S1dUTlJka3h0WkhCa1IyZ3hXV2s1TTJJelNuSmFiWGgyWkROTmRtTnRWbk5hVjBaNldsTTFOV0pYZUVGamJWWnRZM2s1YjFwWFJtdGplVGwwV1Zkc2RRcE5SR2RIUTJselIwRlJVVUpuTnpoM1FWSk5SVXRuZDI5T2FrbDRXbFJSTlU1NlVtcFpWRWt4V1RKVk1VMTZSVE5PZWs1cldsZFpNVTlFV21sWlZFNXNDbHBFYUd4T2VrMHlXV3BPYlZsNlFWVkNaMjl5UW1kRlJVRlpUeTlOUVVWVlFrRlpUVUpJUWpGak1tZDNWMUZaUzB0M1dVSkNRVWRFZG5wQlFrWlJVa3dLUkVWc2IyUklVbmRqZW05MlRESmtjR1JIYURGWmFUVnFZakl3ZG1OSWJIZFpVemw2V1ZjeGQySkhWbmRqYlRseFdsZE9NRXd5Um1wa1IyeDJZbTVOZGdwamJsWjFZM2s0ZUUxVVkzaE5la0Y2VDBSck5FMVRPV2hrU0ZKc1lsaENNR041T0hoTlFsbEhRMmx6UjBGUlVVSm5OemgzUVZKWlJVTkJkMGRqU0ZacENtSkhiR3BOU1VkTFFtZHZja0puUlVWQlpGbzFRV2RSUTBKSWQwVmxaMEkwUVVoWlFUTlVNSGRoYzJKSVJWUktha2RTTkdOdFYyTXpRWEZLUzFoeWFtVUtVRXN6TDJnMGNIbG5Remh3TjI4MFFVRkJSMVJCTlM5WU5VRkJRVUpCVFVGU2VrSkdRV2xCTm01WlN6QkhlSEZXZWtwMWRISnFjbGxCTVdKQlNVdElWUXBxUjNKelNFMU1jazlLVkZSRlZXbEZVa0ZKYUVGS1dtOTBRVlJ1VTNkc1MzUTNRek5hZDJoNE0yWmpVM0pvUjJaUFlXdFViRTB5ZHlzNGNXMXNkR05xQ2sxQmIwZERRM0ZIVTAwME9VSkJUVVJCTW1OQlRVZFJRMDFDSzJsc2MxQm5lVFI1YmxWSE9VZDBjVVJGUW5GWE9DdGFjV3BZTmt4d2RYaFJjV3BEY2pjS2N6UjVkSGwwTW5Cd1JtUm5hbkpIY2tjeFJGazBibE5hZEZGSmQySnNjbWR4T1hRNWFYcEJUVlJyU21WeGFGRkNjekpQVldsNVNVcGFhWEJqWlVRMWRncEJRVVV2VG1ablpDODVkVXN3VFZwQlNFWnpUR2RoYkhGUFFtdzRDaTB0TFMwdFJVNUVJRU5GVWxSSlJrbERRVlJGTFMwdExTMEsifV19fQ==",
58+
"inclusionPromise": {
59+
"signedEntryTimestamp": "MEQCIGzFZon9/joNsiQOL1uoIP/gtz7/A6eAB+50oX3M0CBaAiAZmLVxcgknlWls6R1FswJWCHY0vkwQ/jE5dSkcY43jWA=="
60+
},
61+
"inclusionProof": {
62+
"checkpoint": {
63+
"envelope": "rekor.sigstore.dev - 1193050959916656506\n25232879\nQrnMowJnGj9hZkL1UOvkg7w+KuG27PEDcsdaEqCtoDM=\n\n— rekor.sigstore.dev wNI9ajBFAiEAshgj30XTIU+L6UyYL0yzLXJbLFmxPEc8ZRmS1R3N1sQCIFCjFEqe9J+Et9sWzJp6SE3p7Eh/+97zON7mwX6unCem\n"
64+
},
65+
"hashes": [
66+
"Bc4heeKQhKCr6/ZtuEHmAyp8AzvP4N1ROusEacAmfFQ=",
67+
"ZTeyp2wk6H1Bgz3SZOqQWoQvCmkiltfFstDiy1WaR9Y=",
68+
"vnHPC5XIhbYQib86Hi6M4OaEOFGFMlOip8+5mxZd8cs=",
69+
"BEONTVFois+c47/YA7vzwZG7fbNLBkVLz1hUM/WMb1k=",
70+
"PWqRmPYAwa1fq6R1qSrYlOxCtiKnFZq9hnNt7XwCIA8=",
71+
"KHxYP0XNSf1yKjp+xY/5Kkckw0Yweyjx9Z6qn2+pnZM=",
72+
"8/b9kmTAbALhl4EaKIH4uMXhES9ILB0XQkuH44FltJY=",
73+
"mXfX9NDkaWje6HpniWis2CBELUGjv8LiW2jeMOclCs0=",
74+
"jRPOva2IEma7ZE7mPN3xHtEnXtMF/HNvrmbC5TKTy14=",
75+
"s8vUdxeRlxXWTCMdSLhiSzRiYM3eGsVvrm+5HWkTNBc=",
76+
"4lUF0YOu9XkIDXKXA0wMSzd6VeDY3TZAgmoOeWmS2+Y=",
77+
"gf+9m552B3PnkWnO0o4KdVvjcT3WVHLrCbf1DoVYKFw="
78+
],
79+
"logIndex": "25232877",
80+
"rootHash": "QrnMowJnGj9hZkL1UOvkg7w+KuG27PEDcsdaEqCtoDM=",
81+
"treeSize": "25232879"
82+
},
83+
"integratedTime": "1730932627",
84+
"kindVersion": {
85+
"kind": "dsse",
86+
"version": "0.0.1"
87+
},
88+
"logId": {
89+
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
90+
},
91+
"logIndex": "147137139"
92+
}
93+
]
94+
},
95+
"version": 1
96+
}
97+
],
98+
"publisher": {
99+
"claims": null,
100+
"environment": "",
101+
"kind": "GitHub",
102+
"repository": "pypa/sampleproject",
103+
"workflow": "release.yml"
104+
}
105+
}
106+
],
107+
"version": 1
108+
}
109+
```
110+
111+
#### Status codes
112+
113+
* `200 OK` - no error, provenance is available
114+
* `403 Forbidden` - access is temporarily disabled by the PyPI administrators
115+
* `404 Not Found` - file has no provenance
116+
* `406 Not Acceptable` - `Accept:` header not recognized
117+
118+
[PEP 740]: https://peps.python.org/pep-0740/
119+
120+
[publish attestation]: /attestations/publish/v1
121+
122+
[SLSA Provenance]: https://slsa.dev/spec/v1.0/provenance

Diff for: docs/user/attestations/consuming-attestations.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Consuming attestations
2+
3+
<!--[[ preview('index-attestations') ]]-->
4+
5+
PyPI makes a file's attestations available via the simple index (HTML)
6+
and simple JSON APIs.
7+
8+
For a full API reference, see the [Integrity API documentation].
9+
10+
[Integrity API documentation]: /api/integrity/

Diff for: docs/user/attestations/index.md

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
title: Introduction
3+
---
4+
5+
<!--[[ preview('index-attestations') ]]-->
6+
7+
These pages document PyPI's implementation of digital attestations ([PEP 740]),
8+
including in-toto attestation predicates specific to PyPI itself.
9+
10+
## Quick background
11+
12+
*Digital attestations* enable package maintainers as well as third parties (such
13+
as the index itself, external auditors, etc.) to *cryptographically sign*
14+
for uploaded packages.
15+
16+
These signatures bind each release distribution (such as an individual sdist or
17+
wheel) to a strong cryptographic digest of its contents, allowing both PyPI
18+
and downstream users to verify that a particular package was attested to by
19+
a particular identity (such as a GitHub Actions workflow).
20+
21+
These attestations can take multiple forms, including [publish attestations]
22+
for publicly verifiable proof that a package was published via a specific
23+
[Trusted Publisher], or more general [SLSA Provenance] attesting to a package's
24+
original source location.
25+
26+
## Supported attestations
27+
28+
PyPI uses the [in-toto Attestation Framework] for the attestations it accepts.
29+
30+
Currently, PyPI allows the following attestation predicates:
31+
32+
* [SLSA Provenance]
33+
* [PyPI Publish]
34+
35+
[in-toto Attestation Framework]: https://github.com/in-toto/attestation/blob/main/spec/README.md
36+
37+
[PEP 740]: https://peps.python.org/pep-0740/
38+
39+
[PyPI Publish]: /attestations/publish/v1/
40+
41+
[publish attestations]: /attestations/publish/v1/
42+
43+
[Trusted Publisher]: /trusted-publishers/
44+
45+
[SLSA Provenance]: https://slsa.dev/spec/v1.0/provenance
46+
47+

0 commit comments

Comments
 (0)