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

Google Trusted Publishing docs #15195

Merged
merged 5 commits into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
36 changes: 35 additions & 1 deletion docs/user/trusted-publishers/adding-a-publisher.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,41 @@ each.

=== "Google Cloud"

TODO
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.
di marked this conversation as resolved.
Show resolved Hide resolved

!!! 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

=== "ActiveState"

Expand Down
10 changes: 9 additions & 1 deletion docs/user/trusted-publishers/creating-a-project-through-oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,16 @@ provide the name of the PyPI project that will be created.

=== "Google Cloud"

TODO
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.

=== "ActiveState"

Expand Down
18 changes: 17 additions & 1 deletion docs/user/trusted-publishers/security-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,23 @@ own security model and considerations.

=== "Google Cloud"

TODO
### Security Model

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.
di marked this conversation as resolved.
Show resolved Hide resolved
The identity used for publishing can be optionally constrained further by
specifying the subject, an ID that represents the principal making the request.

### Considerations

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
accounts](https://cloud.google.com/iam/docs/service-account-types#default), as
they are provided by default to every service when they are created.

=== "ActiveState"

Expand Down
51 changes: 50 additions & 1 deletion docs/user/trusted-publishers/using-a-publisher.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,56 @@ below describe the setup process for each supported trusted publisher.

=== "Google Cloud"

TODO
You can use the <https://pypi.org/project/id/> tool to automatically detect
and produce OIDC credentials on Google Cloud services.

First, ensure that `id` and `twine` are installed in the environment you
plan to publish from:

```
$ python -m pip install -U id twine
```

If you're unsure what the email address is for the service account your
service is using, you can verify it with:

```
$ python -m id pypi -d | jq 'select(.email) | .email'
```

Generate an OIDC token from within the environment and store it. The
audience should be either `pypi` or `testpypi` depending on which index you are
publishing to:

```
$ oidc_token=$(python -m id pypi)
```

**NOTE**: `pypi` is only correct for PyPI. For TestPyPI, the correct
audience is `testpypi`. More generally, you can access any instance's expected
OIDC audience via the `{index}/_/oidc/audience` endpoint:

```console
$ curl https://pypi.org/_/oidc/audience
{"audience":"pypi"}
```
di marked this conversation as resolved.
Show resolved Hide resolved

Finally, we can submit that token to PyPI and get a short-lived API token
back:

```bash
resp=$(curl -X POST https://pypi.org/_/oidc/mint-token -d "{\"token\": \"${oidc_token}\"}")
api_token=$(jq '.token' <<< "${resp}")
di marked this conversation as resolved.
Show resolved Hide resolved
```

**NOTE**: This is the URL for PyPI. For TestPyPI, the correct
domain should be is `test.pypi.org`.
di marked this conversation as resolved.
Show resolved Hide resolved

This API token can be fed into `twine` or any other uploading client:

```bash
TWINE_USERNAME=__token__ TWINE_PASSWORD="${api_token}" twine upload dist/*
di marked this conversation as resolved.
Show resolved Hide resolved
```

=== "ActiveState"

Expand Down