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

Document additional Trusted Publishers #15192

Merged
merged 35 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c911f33
docs/user: empty sections for more publishers
woodruffw Jan 10, 2024
9219252
Fix headings
di Jan 11, 2024
6599491
Add provider TODOs to using-a-publisher.md
di Jan 11, 2024
62be887
Move images into provider-specific directories
di Jan 11, 2024
f0aef1a
Update GitHub screenshots
di Jan 11, 2024
f75bc65
Fix asset links
di Jan 11, 2024
a973d38
Update admonition to match
di Jan 12, 2024
f849aee
Remove unnecessary quoting
di Jan 13, 2024
656637e
Google Trusted Publishing docs (#15195)
di Jan 13, 2024
0bfd2fc
Add Google screenshots
di Jan 13, 2024
fc699e0
Fix provider-specific screenshots
di Jan 13, 2024
db9c99b
Add GitLab Trusted Publishing docs (#15283)
facutuesca Feb 23, 2024
c78f60e
Merge branch 'main' into more-oidc-docs
di Mar 6, 2024
b9b1532
Add activestate OIDC docs (#15548)
th3coop Mar 20, 2024
8cc6ee5
Slugify tab anchors
di Mar 22, 2024
6f1c8b2
Add blogpost announcing more trusted publishers (#15656)
di Mar 22, 2024
a5f0e0b
Merge branch 'main' into more-oidc-docs
di Mar 22, 2024
0b75a2d
Updating ActiveState publishing docs (#15739)
rawktron Apr 9, 2024
b5fb60d
Update publish date
di Apr 10, 2024
d9c6e7e
Merge branch 'main' into more-oidc-docs
di Apr 10, 2024
10cd258
Update line for consistency
di Apr 16, 2024
0f14fce
Update tabbed headings to not appear in ToC
di Apr 16, 2024
ccbb7ee
Wrap long lines
di Apr 16, 2024
1baa169
Consistency fix
di Apr 16, 2024
70d2306
Line break
di Apr 16, 2024
d46b615
Strip out leading $
di Apr 16, 2024
05ecc46
Make note conform
di Apr 16, 2024
93333b0
Translations
di Apr 16, 2024
461e93c
Add border to images
di Apr 16, 2024
278744b
Update screenshot
di Apr 16, 2024
f1d1d8e
Dark mode CSS doesn't work as expected
di Apr 16, 2024
56cf575
Add alt text
di Apr 16, 2024
8b0fcc7
Merge branch 'main' into more-oidc-docs
di Apr 16, 2024
4789ddf
Update publication date
di Apr 16, 2024
7fa8d2a
Fix ActiveState getting started Trusted Publisher links (#15801)
th3coop Apr 16, 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
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ providing valuable feedback to improve this feature along the way.

---

_Dustin Ingram is a maintainer of the Python Package Index and a director of
the Python Software Foundation._
_Dustin Ingram is a maintainer of the Python Package Index._

[^1]: Currently, information such as this are provided by the uploader and are not verified as accurate by PyPI.
[OpenID Connect (OIDC)]: https://openid.net/connect/
Expand Down
66 changes: 66 additions & 0 deletions docs/blog/posts/2024-04-15-expanding-trusted-publisher-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Expanding Trusted Publisher Support
description: Announcing additional Trusted Publishing providers
authors:
- di
date: 2024-04-15
tags:
- publishing
- security
- oidc
---

Starting today, PyPI package maintainers can publish via Trusted Publishing
from three additional providers:

* GitLab CI/CD
* Google Cloud
* ActiveState

These providers join existing support for publishing from GitHub Actions without
long-lived passwords or API tokens, which [we announced last year], and bring
support for Trusted Publishing to even more hosted providers.

<!-- more -->

### About Trusted Publishing

Trusted Publishing is our term for using the [OpenID Connect (OIDC)] 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 username/password combinations or long-lived, manually generated
API tokens to authenticate with PyPI when publishing.

Instead, maintainers can configure PyPI to trust an identity provided by a
given OpenID Connect Identity Provider (IdP). This allows allows PyPI to verify
and delegate trust to that identity, which is then authorized to request
short-lived, tightly-scoped API tokens from PyPI. These API tokens never need
to be stored or shared, rotate automatically by expiring quickly, and provide a
verifiable link between a published package and its source.

### Get started today

To get started with using trusted publishers on PyPI, see our documentation
here: <https://docs.pypi.org/trusted-publishers/>.

### Acknowledgements

Funding for work implementing Google Cloud and GitLab support was provided by
the Google Open Source Security Team, and much of the development work was
performed by [Trail of Bits], with special thanks to contributors [William
Woodruff] and [Facundo Tuesca].

ActiveState support was provided by ActiveState, with special thanks to
contributors [Carey Hoffman] and [Pete Garcin].

---

_Dustin Ingram is a maintainer of the Python Package Index._

[we announced last year]: 2023-04-20-introducing-trusted-publishers.md
[William Woodruff]: https://github.com/woodruffw
[Facundo Tuesca]: https://github.com/facutuesca
[Carey Hoffman]: https://github.com/th3coop
[Pete Garcin]: https://github.com/rawktron
[OpenID Connect (OIDC)]: https://openid.net/connect/
[Trail of Bits]: https://www.trailofbits.com/
1 change: 1 addition & 0 deletions docs/mkdocs-user-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ markdown_extensions:
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: lower}}
- tables
theme:
name: material
Expand Down
Binary file not shown.
Binary file not shown.
Binary file removed docs/user/assets/project-publisher-registered.png
Binary file not shown.
Binary file removed docs/user/assets/project-publishing-form.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
di marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
di marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 90 additions & 9 deletions docs/user/trusted-publishers/adding-a-publisher.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ 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:

![](/assets/manage-link.png)
![](/assets/trusted-publishing/manage-link.png)

Then, click on "Publishing" in the project's sidebar:

![](/assets/project-publishing-link.png)
![](/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
Expand All @@ -34,7 +34,7 @@ each.
that uses a publishing workflow defined in `.github/workflows/release.yml`
and a custom environment named `release`, then you'd do the following:

![](/assets/project-publishing-form.png)
![](/assets/trusted-publishing/github/project-publishing-form.png)

!!! note

Expand All @@ -43,15 +43,96 @@ each.
your trusted workflow, such as requiring manual approval on each run
by a trusted subset of repository maintainers.

Once you click "Add", your publisher will be registered and will appear
at the top of the page:

Once you click "Add", your publisher will be registered and will appear
at the top of the page:
![](/assets/trusted-publishing/github/project-publisher-registered.png)

![](/assets/project-publisher-registered.png)
From this point onwards, the `release.yml` workflow on `octo-org/sampleproject` will
be able to generate short-lived API tokens from PyPI for the project you've registered
it against.

From this point onwards, the `release.yml` workflow on `octo-org/sampleproject` will
be able to generate short-lived API tokens from PyPI for the project you've registered
it against.
=== "Google Cloud"

For Google Cloud, you **must** provide the email address of the account or
service account used to publish. [You can learn more about Google Cloud
service accounts
here](https://cloud.google.com/iam/docs/service-account-overview).

For example, if you have created a service account named
"SERVICE_ACCOUNT_NAME" in the project "PROJECT_NAME" which is in use by
the environment where you would like to publish to PyPI from, your service
account email would take the form
`SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com`, and you would do
the following:

![](/assets/trusted-publishing/google/project-publishing-form.png)

!!! warning

Google Cloud also provides [default service
accounts](https://cloud.google.com/iam/docs/service-account-types#default)
for various products:

* Compute Engine: `[email protected]`
* App Engine: `[email protected]`

However it is **not** recommended that these be used for publishing, as
they are provided by default to every service when they are created.

!!! note

Configuring the subject is optional. The subject is the numeric ID that
represents the principal making the request. While not required, providing the
subject further restricts the identity which is used for publishing, ensuring
that only a specific instance of a service account can publish, not any service
account with the configured email. See
<https://cloud.google.com/docs/authentication/token-types#id-contents>
for more details

Once you click "Add", your publisher will be registered and will appear
at the top of the page:

![](/assets/trusted-publishing/google/project-publisher-registered.png)

=== "ActiveState"

For ActiveState, you need to provide the name of the ActiveState project,
di marked this conversation as resolved.
Show resolved Hide resolved
the ActiveState organization that project belongs to, and the ActiveState user performing
the publish action. Learn more about getting set up on the ActiveState Platform [here](https://docs.activestate.com/platform/start/PYPI).
![](/assets/trusted-publishing/activestate/project-publishing-form.png)
Once you click "Add", your publisher will be registered and will appear at the top of the page:
![](/assets/trusted-publishing/activestate/project-publisher-registered.png)

=== "GitLab CI/CD"

For GitLab CI/CD, you **must** provide the repository's namespace, the
repository's name, and the filepath of the GitLab CI/CD workflow that's
authorized to upload to PyPI. In addition, you may **optionally**
provide the name of a
[GitLab CI/CD environment](https://docs.gitlab.com/ee/ci/environments/).

For example, if you have a project at `https://gitlab.com/namespace/sampleproject`
that uses a publishing workflow defined in `release.yml` and a custom
environment named `release`, then you'd do the following:

![](/assets/trusted-publishing/gitlab/project-publishing-form.png)

!!! note

Configuring an environment is optional, but **strongly** recommended:
with a GitLab environment, you can apply additional restrictions to
your trusted workflow, such as requiring manual approval on each run
by a trusted subset of repository maintainers.

Once you click "Add", your publisher will be registered and will appear
at the top of the page:

![](/assets/trusted-publishing/gitlab/project-publisher-registered.png)

From this point onwards, the `release.yml` workflow on `namespace/sampleproject`
will be able to generate short-lived API tokens from PyPI for the project you've
registered it against.

A publisher can be registered against multiple PyPI projects (e.g. for a
multi-project repository), and a single PyPI project can have multiple
Expand Down
57 changes: 53 additions & 4 deletions docs/user/trusted-publishers/creating-a-project-through-oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The steps for configuring a "pending" publisher are similar to those for
a normal publisher, except that the page is under your account sidebar
instead of any project's sidebar (since the project doesn't exist yet):

![](/assets/publishing-link.png)
![](/assets/trusted-publishing/publishing-link.png)
di marked this conversation as resolved.
Show resolved Hide resolved

Clicking on "publishing" will bring you to a page with different potential
trusted publishers. The forms on this page behave
Expand All @@ -32,17 +32,66 @@ provide the name of the PyPI project that will be created.
`release.yml` and an environment named `release` that you would like to publish
to PyPI as `sampleproject`, then you would do the following:

![](/assets/pending-publisher-form-filled.png)
![](/assets/trusted-publishing/github/pending-publisher-form-filled.png)

!!! note

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

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

![](/assets/trusted-publishing/github/pending-publisher-registered.png)

=== "Google Cloud"

If you have a service account named
`SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com`, which is in use by
the environment where you would like to publish to PyPI from, then you would do
the following:

![](/assets/trusted-publishing/google/pending-publisher-form-filled.png)

!!! note

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

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

![](/assets/trusted-publishing/google/pending-publisher-registered.png)

=== "ActiveState"

Setting up ActiveState to create a PyPI project is the same as
updating a project. You need to provide the name of the ActiveState project,
the ActiveState organization that project belongs to, and the ActiveState user who will be performing
the publish action. Learn more about getting set up on the ActiveState Platform [here](https://docs.activestate.com/platform/start/PYPI).
di marked this conversation as resolved.
Show resolved Hide resolved

![](/assets/trusted-publishing/activestate/pending-publisher-form-filled.png)

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

![](/assets/trusted-publishing/activestate/pending-publisher-registered.png)

=== "GitLab CI/CD"

If you have a repository at
`https://gitlab.com/namespace/sampleproject` with a release workflow at
`release.yml` and an environment named `release` that you would like to publish
to PyPI as `sampleproject`, then you would do the following:

![](/assets/trusted-publishing/gitlab/pending-publisher-form-filled.png)

!!! note

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

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

![](/assets/trusted-publishing/gitlab/pending-publisher-registered.png)

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

![](/assets/pending-publisher-registered.png)

From this point on, the "pending" publisher can be used exactly like a
"normal" publisher, and after first use it will convert it into a "normal"
Expand Down
Loading