Skip to content

Commit

Permalink
docs: use Trusted Publishing uniformly as a term of art (#17267)
Browse files Browse the repository at this point in the history
Signed-off-by: William Woodruff <[email protected]>
Co-authored-by: Dustin Ingram <[email protected]>
  • Loading branch information
woodruffw and di authored Dec 12, 2024
1 parent 9a38f0a commit e6bdf57
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 61 deletions.
6 changes: 3 additions & 3 deletions docs/user/trusted-publishers/adding-a-publisher.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
title: Adding a Trusted Publisher to an Existing PyPI Project
---

# Adding a trusted publisher to an existing PyPI project
# Adding a Trusted Publisher to an existing PyPI project

Adding a trusted publisher to a PyPI project only requires a single setup step.
Adding a Trusted Publisher to a PyPI project only requires a single setup step.

On the ["Your projects" page](https://pypi.org/manage/projects/), click "Manage" on any project you'd like to
configure:
Expand All @@ -16,7 +16,7 @@ Then, click on "Publishing" in the project's sidebar:
![Image showing the 'Publishing' link in the project sidebar](/assets/trusted-publishing/project-publishing-link.png)

That link will take you to the publisher configuration page for the project,
which will allow you to configure trusted publishers for the different
which will allow you to configure Trusted Publishers for the different
platforms supported by PyPI (such as GitHub Actions).

To enable a publisher, you need to tell PyPI how to trust it. Each trusted
Expand Down
12 changes: 6 additions & 6 deletions docs/user/trusted-publishers/creating-a-project-through-oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
title: Creating a PyPI Project with a Trusted Publisher
---

# Creating a PyPI project with a trusted publisher
# Creating a PyPI project with a Trusted Publisher

Trusted publishers are not just for pre-existing PyPI projects: you can also use
Trusted Publishers are not just for pre-existing PyPI projects: you can also use
them to *create* a PyPI project!

This again reduces the number of steps needed to set up a fully automated PyPI
Expand All @@ -21,7 +21,7 @@ instead of any project's sidebar (since the project doesn't exist yet):
![Image showing the 'Publishing' link in the account sidebar](/assets/trusted-publishing/publishing-link.png)

Clicking on "publishing" will bring you to a page with different potential
trusted publishers. The forms on this page behave
Trusted Publishers. The forms on this page behave
the same as with publishers for existing projects, except that you also need to
provide the name of the PyPI project that will be created.

Expand All @@ -45,7 +45,7 @@ provide the name of the PyPI project that will be created.

!!! note

Like with "normal" trusted publishers, configuring a GitHub Actions
Like with "normal" Trusted Publishing, configuring a GitHub Actions
environment is **optional but strongly recommended**.

Clicking "Add" will register the "pending" publisher, and show it to you:
Expand All @@ -63,7 +63,7 @@ provide the name of the PyPI project that will be created.

!!! note

Like with "normal" trusted publishers, configuring the subject is optional.
Like with "normal" Trusted Publishing, configuring the subject is optional.

Clicking "Add" will register the "pending" publisher, and show it to you:

Expand Down Expand Up @@ -98,7 +98,7 @@ provide the name of the PyPI project that will be created.

!!! note

Like with "normal" trusted publishers, configuring a GitLab CI/CD
Like with "normal" Trusted Publishing, configuring a GitLab CI/CD
environment is **optional but strongly recommended**.

Clicking "Add" will register the "pending" publisher, and show it to you:
Expand Down
6 changes: 3 additions & 3 deletions docs/user/trusted-publishers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Getting Started

# Publishing to PyPI with a Trusted Publisher

"Trusted publishing" is our term for using the [OpenID Connect
"Trusted Publishing" is our term for using the [OpenID Connect
(OIDC)](https://openid.net/connect/) standard to exchange short-lived identity
tokens between a trusted third-party service and PyPI. This method can be used
in automated environments and eliminates the need to use manually generated API
Expand Down Expand Up @@ -42,10 +42,10 @@ the TL;DR:
This confers significant usability and security advantages when compared
to PyPI's traditional authentication methods:

* Usability: with trusted publishing, users no longer need to manually create
* Usability: with Trusted Publishing, users no longer need to manually create
API tokens on PyPI and copy-paste them into their CI provider. The only
manual step is configuring the publisher on PyPI.
* Security: PyPI's normal API tokens are long-lived, meaning that an attacker
who compromises a package's release token can use it until its legitimate user
notices and manually revokes it. Trusted publishing avoids this problem because
notices and manually revokes it. Trusted Publishing avoids this problem because
the tokens minted expire automatically.
40 changes: 20 additions & 20 deletions docs/user/trusted-publishers/internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ title: Internals and Technical Details
It's intended primarily for PyPI developers and developers of other
package indices looking to support similar authentication models.

## How trusted publishing works
## How Trusted Publishing works

PyPI's trusted publishing functionality is built on top of
PyPI's Trusted Publishing functionality is built on top of
[OpenID Connect], or "OIDC" for short.

OIDC gives *services* (like GitHub Actions) a way to *provably identify*
Expand All @@ -22,7 +22,7 @@ workflow) can present an *OIDC token* to a third-party service. That
party service can then verify the token and determine whether it's
authorized to perform some other action.

In the context of trusted publishing, the machinery is as follows:
In the context of Trusted Publishing, the machinery is as follows:

* *OIDC identity providers* like GitHub ("providers" for short) generate OIDC
tokens that contain scoped *claims*, which convey appropriate authorization
Expand All @@ -32,11 +32,11 @@ In the context of trusted publishing, the machinery is as follows:
`octo-org/example`, indicating that the token should be authorized
to access resources for which `octo-org/example` is a valid repository.

* *Trusted publishers* are pieces of configuration on PyPI that tell PyPI
* *Trusted Publishers* are pieces of configuration on PyPI that tell PyPI
*which* OIDC providers to trust, and *when* (i.e., which specific set
of claims to consider valid).

* For example, a trusted publisher configuration for GitHub Actions might
* For example, a Trusted Publisher configuration for GitHub Actions might
specify `repo: octo-org/example` with `workflow: release.yml` and
`environment: pypi`, indicating that a presented OIDC token **must**
contain exactly those claims to be considered valid.
Expand All @@ -50,26 +50,26 @@ In the context of trusted publishing, the machinery is as follows:
endpoint.

* Token exchange boils down to a matching process between a presented
OIDC token and every trusted publisher currently configured on PyPI:
OIDC token and every Trusted Publisher currently configured on PyPI:
the token's signature is first verified (to ensure that it's actually
coming from the expected provider), and then its claims are matched
against zero or more projects with registered trusted publishers.
against zero or more projects with registered Trusted Publishers.

If the OIDC token corresponds to one or more trusted publishers, then
If the OIDC token corresponds to one or more Trusted Publishers, then
a short-lived (15 minute) PyPI API token is issued. This API token
is scoped to every project with a matching trusted publisher, meaning
is scoped to every project with a matching Trusted Publisher, meaning
that it can be used to upload to multiple projects (if so configured).

If everything goes correctly, a successful trusted publishing flow results in
If everything goes correctly, a successful Trusted Publishing flow results in
a short-lived PyPI API token *without any user interaction*, which in turn
offers security and ergonomic benefits to PyPI packagers: users no longer
have to worry about token provisioning or revocation.

## Q&A

### Why does trusted publishing use a "two-phase" token exchange?
### Why does Trusted Publishing use a "two-phase" token exchange?

As noted above, trusted publishing uses a "token exchange" mechanism, which
As noted above, Trusted Publishing uses a "token exchange" mechanism, which
happens in two phases:

1. The uploading client presents an OIDC token, which PyPI verifies.
Expand Down Expand Up @@ -135,12 +135,12 @@ do similar "two-phase" exchange mechanisms.

### Why is the PyPI project to publisher relationship "many-many"?

If you play around with trusted publishers on PyPI, you'll notice that
If you play around with Trusted Publishing on PyPI, you'll notice that
PyPI projects can have multiple publishers, and individual publishers
can be registered to multiple projects.

This is a "many-many" relationship between PyPI projects and their trusted
publishers which, like "two-phase" exchange, seems more complicated in
This is a "many-many" relationship between PyPI projects and their Trusted
Publishers which, like "two-phase" exchange, seems more complicated in
principle than necessary.

In practice, this many-many relationship addresses publishing patterns commonly
Expand All @@ -152,7 +152,7 @@ used by the Python packaging community:
workflow, due to tandem releases (e.g., a simultaneous release
of a library package and its corresponding CLI tool).

Trusted publishing's design accommodates this use case: maintainers
Trusted Publishing's design accommodates this use case: maintainers
can use the same `release.yml` workflow for all of their packages,
rather than having to split it up by packages.

Expand All @@ -173,9 +173,9 @@ used by the Python packaging community:
builds in a final platform-agnostic publishing step, which could then
be a single publisher.

However, in the interest of getting trusted publishers into users' hands
However, in the interest of getting Trusted Publishers into users' hands
without requiring them to make significant unrelated changes to the builds,
the trusted publishing feature allows users to register multiple
the Trusted Publishing feature allows users to register multiple
publishers against a single project. Consequently, `sampleproject`
can be published from both `release-linux.yml` and `release-macos.yml`
without needing to be refactored into a single `release.yml`.
Expand All @@ -184,7 +184,7 @@ used by the Python packaging community:

Some OIDC providers support username changes, so a claim of
`repository_owner: octo-org` might not necessarily refer to the same `octo-org`
that a user initially authorized in a trusted publisher configuration.
that a user initially authorized in a Trusted Publisher configuration.

If a repository owner changes their username or deletes their account, a
malicious actor may be able to take the freed username and create their
Expand All @@ -193,7 +193,7 @@ resurrection attack*.

To solve this issue for GitHub-based publishers, PyPI always checks the
`repository_owner_id` claim. This claim attests to the ID of the repository
owner, which is stable and permanent unlike usernames. When a trusted publisher
owner, which is stable and permanent unlike usernames. When a Trusted Publisher
is configured, PyPI looks up the configured username's ID and stores it. During
API token minting, PyPI checks the `repository_owner_id` claim against the
stored ID and fails if they don't match. Through this process, only the original
Expand Down
34 changes: 17 additions & 17 deletions docs/user/trusted-publishers/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ is not a panacea. In particular:
OIDC tokens are also short-lived, but an attacker who successfully intercepts
one can mint API tokens against it for as long as it lives.

* Configuring a trusted publisher means establishing trust in a particular piece
* Configuring a Trusted Publisher means establishing trust in a particular piece
of external state (such as a GitHub Actions workflow); that state **must not**
be controllable by untrusted parties.

In summary: treat your trusted publishers *as if* they were API tokens. If you
In summary: treat your Trusted Publishers *as if* they were API tokens. If you
wouldn't let a user or piece of code access your API token, then they shouldn't
be able to invoke your trusted publisher.
be able to invoke your Trusted Publisher.

## Provider-specific considerations

Each trusted publishing provider is its own OIDC identity provider, with its
Each Trusted Publishing provider is its own OIDC identity provider, with its
own security model and considerations.

=== "GitHub Actions"
Expand Down Expand Up @@ -57,7 +57,7 @@ own security model and considerations.

<h3>Considerations</h3>

* In particular, for trusted publishing with GitHub Actions, you
* In particular, for Trusted Publishing with GitHub Actions, you
**must**:

* Trust the correct username and repository: if you trust a repository
Expand All @@ -81,17 +81,17 @@ own security model and considerations.
This particular risk can be mitigated by using a dedicated environment
with manual approvers, as described below.

* Trusted publishers are registered to projects, not to users. This means that
removing a user from a PyPI project does **not** remove any trusted publishers
* Trusted Publishers are registered to projects, not to users. This means that
removing a user from a PyPI project does **not** remove any Trusted Publishers
that they might have registered, and that you should include a review
of any/all trusted publishers as part of "offboarding" a project maintainer.
of any/all Trusted Publishers as part of "offboarding" a project maintainer.

PyPI has protections in place to make some attacks against OIDC more difficult
(like [account resurrection attacks]). However, like all forms of authentication,
the end user is **fundamentally responsible** for applying it correctly.

In addition to the requirements above, you can do the following to
"ratchet down" the scope of your trusted publishing workflows:
"ratchet down" the scope of your Trusted Publishing workflows:

* **Use per-job permissions**: The `permissions` key can be defined on the
workflow level or the job level; the job level is **always more secure**
Expand Down Expand Up @@ -135,7 +135,7 @@ own security model and considerations.

<h3>Security Model</h3>

If a trusted publisher is configured for a given PyPI project, any service
If a Trusted Publisher is configured for a given PyPI project, any service
that uses the configured service account can request an OpenID Connect token
from Google's identity provider on behalf of that identity. That token can be
exchanged for a PyPI API token with the ability to publish to the PyPI project.
Expand All @@ -144,7 +144,7 @@ own security model and considerations.

<h3>Considerations</h3>

When using trusted publishing with Google Cloud, you must trust the service account
When using Trusted Publishing with Google Cloud, you must trust the service account
and _any service which uses it as the default ephemeral identity_.

Specifically, it is not recommened to configure the [default service
Expand Down Expand Up @@ -184,14 +184,14 @@ own security model and considerations.
repository located at orgA/repo cannot impersonate a repository located at orgB/repo.
* The claims defined in an OIDC token are *bound to the top-level pipeline*, meaning
that any pipeline included by the top-level pipeline (usually `.gitlab-ci.yml`)
will be able to upload using a trusted publisher that trusts the `.gitlab-ci.yml`
will be able to upload using a Trusted Publisher that trusts the `.gitlab-ci.yml`
pipeline.
* An OIDC token for a specific repository and pipeline can be generated by anyone
who has permissions to run that pipeline in the repository's CI/CD.

<h3>Considerations</h3>

* In particular, for trusted publishing with GitLab CI/CD, you
* In particular, for Trusted Publishing with GitLab CI/CD, you
**must**:

* Trust the correct namespace and repository: if you trust a repository
Expand Down Expand Up @@ -219,13 +219,13 @@ own security model and considerations.
This particular risk can be mitigated by using a dedicated environment
with manual approvers, as described below.

* Trusted publishers are registered to projects, not to users. This means that
removing a user from a PyPI project does **not** remove any trusted publishers
* Trusted Publishers are registered to projects, not to users. This means that
removing a user from a PyPI project does **not** remove any Trusted Publishers
that they might have registered, and that you should include a review
of any/all trusted publishers as part of "offboarding" a project maintainer.
of any/all Trusted Publishers as part of "offboarding" a project maintainer.

In addition to the requirements above, you can do the following to
"ratchet down" the scope of your trusted publishing workflows:
"ratchet down" the scope of your Trusted Publishing workflows:

* **[Use a dedicated environment](https://docs.gitlab.com/ee/ci/environments/)**:
GitLab CI/CD supports "environments", which can be used to isolate secrets to
Expand Down
10 changes: 5 additions & 5 deletions docs/user/trusted-publishers/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ title: Troubleshooting

## Reusable workflows on GitHub

[Reusable workflows] cannot currently be used as the workflow in a trusted
publisher. This is a practical limitation, and is being tracked in
[Reusable workflows] cannot currently be used as the workflow in a Trusted
Publisher. This is a practical limitation, and is being tracked in
[warehouse#11096].

## Ratelimiting

PyPI currently imposes ratelimits on trusted publisher registration: no more
PyPI currently imposes rate limits on Trusted Publisher registration: no more
than 100 publishers can be registered by a single user or IP address within a 24
hour window.

Expand Down Expand Up @@ -89,13 +89,13 @@ To fix this, you must determine which of the two names is the correct one:

* If the name used in the pending publisher is the correct one, then you must
update your project metadata to reflect that name. Subsequent uploads with the
trusted publisher will work automatically, and no further action is required.
Trusted Publisher will work automatically, and no further action is required.

* If the name used in the project metadata is the correct one, then you must:

1. Go to [your projects] and delete the incorrectly created project.
This will also have the effect of deleting the incorrectly registered
trusted publisher.
Trusted Publisher.

2. Create a new pending publisher with the corrected project name.

Expand Down
Loading

0 comments on commit e6bdf57

Please sign in to comment.