Skip to content

[aug 8 merge] review: trusted publishing tutorial #561

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

lwasser
Copy link
Member

@lwasser lwasser commented Jul 22, 2025

This adds the trusted publishing tutorial as a pr so we can spend time reviewing it. Relates to #253 submitted by @mihaimaruseac

let's leave this page open for a few weeks to allow for time to review!

@lwasser lwasser changed the title review: trusted publishing tutorial [aug 8 merge] review: trusted publishing tutorial Jul 22, 2025
Copy link
Contributor

@Midnighter Midnighter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just read the tutorial online and it is well structured, has good language, sane content, and I didn't miss anything.

👍🏼 from me.

Copy link
Contributor

@mihaimaruseac mihaimaruseac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (cannot approve/request changes, but it looks good to me)

Copy link
Collaborator

@ucodery ucodery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guide is GREAT!

Comment on lines +27 to +29
configure automated testing for every pull request, automated publishing of
documentation, automated creation of webpages for the project, and even automate
the release process. For this lesson we will only focus on the release process
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
configure automated testing for every pull request, automated publishing of
documentation, automated creation of webpages for the project, and even automate
the release process. For this lesson we will only focus on the release process
configure automated testing for every pull request, automate publishing of
documentation, automate creation of webpages for the project, and even automate
the release process. For this lesson we will only focus on the release process

:::{admonition} Learning Objectives
:class: tip

This tutorial assumes that your project is published to GitHub and that you want
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"hosted on GitHub"? Github also has its own packages feature that isn't being used here (doesn't work with Python).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, hosted is better here

Suggested change
This tutorial assumes that your project is published to GitHub and that you want
This tutorial assumes that your project is hosted to GitHub and that you want

chain attack due to GitHub Actions is the recent `tj-actions/changed-files`
attack[^changed-files-supply-chain-attack]). Enabling Dependabot[^dependabot] in
the repository will ensure that you always get a PR to keep the actions up to
date.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even for those not concerned about security, actions can be pinned to a version so that when a breaking change is introduced, your workflows do not break and you can upgrade when you have time (actions/checkout@v4).
Maybe that is too TMO for this guide. But also, I worry about posting hash-commits in a guide that will likely be copy-pasted.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be put it in a footnote and then have all examples use the tags instead?


:::

Now, you can commit the `.github/workflows/release.yaml` file to the repository.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Now, you can commit the `.github/workflows/release.yaml` file to the repository.
Now, you can commit the `.github/workflows/release.yaml` file to the repository and push to GitHub.

If the commit is not on GitHub, and the owner creates a new release, that release won't do anything.

Copy link
Contributor

@sneakers-the-rat sneakers-the-rat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super good, love it. The one thing I think would make it even better is to lead with an example scenario to motivate the reason for having trusted publishers in the first place. I think the idea of supply chain vulns would probably not be familiar to tutorial readers, so a scenario like "so you've written a very cool thing and other people are using it and depending on it. So far you've been just publishing from your laptop , but one day you accidentally copy paste your password into bluesky (or whatever lol) and someone swipes it before you delete it! Now they are using your cool thing to steal other people's credit cards, that's not good! We can make things easier for ourselves as well as avoiding a certain category of attacks by..."

Just an example, hopefully u know what I'm saying. Bonus points for using a real example too :)

Good addition!!! I'll probs add an appendix for codeberg which doesn't have trusted publishing if we don't already have something for that already after this is merged.

To get started, create a file named `release.yaml` under the `.github/workflows`
directory of your project.

:::{admonition} Naming the workflow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe as a footnote or collapsed admonition? Good info for newbies, a little bit distracting from flow of prose. Not strong opinion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Footnote seems good to me, thank you!

this GitHub Action on the "Actions" tab in the GitHub repository.

:::{figure-md} github-actions-release-workflows-summary
<img src="../images/tutorials/github-actions-release-workflows-summary.png" alt='Graphic showing an example of a configured workflow for the release. On the top, in the red box labeled "1" you see the "Actions" tab of the GitHub repository. On the left, in the red box labeled "2" you can see the name of the workflow, as configured in this step. Finally, in the center, in the red box labeled "3" you can see several runs of the workflow, for the "1.0" and "1.0.1" releases of the package.' width="700px">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<img src="../images/tutorials/github-actions-release-workflows-summary.png" alt='Graphic showing an example of a configured workflow for the release. On the top, in the red box labeled "1" you see the "Actions" tab of the GitHub repository. On the left, in the red box labeled "2" you can see the name of the workflow, as configured in this step. Finally, in the center, in the red box labeled "3" you can see several runs of the workflow, for the "1.0" and "1.0.1" releases of the package.' width="700px">
<img src="../images/tutorials/github-actions-release-workflows-summary.png" alt='Graphic showing an example of a configured workflow for the release. On the top, in the red box labeled "1" you see the "Actions" tab of the GitHub repository. On the left, in the red box labeled "2" you can see the name of the workflow, "Release," as configured in this step. Finally, in the center, in the red box labeled "3" you can see several runs of the workflow, for the "1.0" and "1.0.1" releases of the package.' width="700px">

Thanks for the good alt text!

### Step 2: Add triggers to the workflow

Every GitHub Actions workflow runs only when certain conditions are met. A
release workflow should only run when the repository owner creates a new release
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
release workflow should only run when the repository owner creates a new release
release workflow should only run when the repository owner creates a new [release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)

Not sure if the idea of a github release will be familiar ATP in the tutorials


### Step 2: Add triggers to the workflow

Every GitHub Actions workflow runs only when certain conditions are met. A
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Every GitHub Actions workflow runs only when certain conditions are met. A
Every GitHub Actions workflow runs only when [certain conditions](https://docs.github.com/en/actions/reference/events-that-trigger-workflows) are met. A


### Step 3: Configure the jobs in the workflow

When triggered, the GitHub Actions runs multiple jobs. We have to configure at
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On phone so can't suggest over multiple lines, but may be worth structuring sentence to emphasize the three things in play, workflow, jobs, steps. Dont accept this bc the footnote should not break up the sentence, but writing it as example.

Suggested change
When triggered, the GitHub Actions runs multiple jobs. We have to configure at
A GitHub Actions *workflow* file can contain multiple *jobs* that run independently, each of which can have multiple *steps.*
When triggered, the GitHub Actions runs all the jobs in a workflow[^conditionally]. We have to configure at
[^conditionally]: Jobs and steps can also have [conditional logic](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idif) that makes them only run in certain circumstances.

of the token could allow attackers to publish new packages in your name, until
you discover the compromise and revoke the leaked credential.

To prevent these incidents and improve security, supply chain security
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To prevent these incidents and improve security, supply chain security
To prevent these incidents and improve supply chain security

you discover the compromise and revoke the leaked credential.

To prevent these incidents and improve security, supply chain security
developers created Trusted Publishing. This allows registering publishers on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
developers created Trusted Publishing. This allows registering publishers on
developers created [Trusted Publishing](https://docs.pypi.org/trusted-publishers/). This allows registering publishers on

Once you fill in this form and click "Add" the publisher is configured and can
be used to publish new releases of your package.

:::{admonition} Fully hardened GitHub Actions release workflow
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be pedantic, but I'm always a bit wary to give the impressions to newbies that security can be "completed" because it might lead to thinking "I'm fully secure, so whatever I do is fine now!"

:::{admonition} Fully hardened GitHub Actions release workflow

For better security it is recommended to also control the permissions of the
GitHub token used within each job of the workflow. The permissions should be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little example might be helpful: "for example, if one of your dependencies was taken over by a malicious actor and embedded code to steal environment variables... since the only code running in the publish step is the trusted publisher action..."


## You have enabled trusted publishing for your project

Congratulations. You have now configured your project to do secure releases when a new version is being tagged on GitHub. The workflow we have configured builds the package from the exact version of code that we are tagging. This provides a guarantee for your users that the package we have released does exactly what the code states it does -- there is no potential for supply chain related vulnerabilities arising from our package! If you have a package that is ready for real-world use on the real PyPI, then you can follow the same steps to publish it securely.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still some possibility! But we have reduced the possibility and made it convenient to publish.

Copy link

@mathematicalmichael mathematicalmichael left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is fantastic.

does the packaging here presume automatic versioning of the package based on tag (or is it useful to remind the user to "stage" their pyproject.toml for publication by specifying the release version and then creating a release to match it?)


# Setup Trusted Publishing for secure and automated publishing via GitHub Actions

In the previous Python packaging lessons, you've learned:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In the previous Python packaging lessons, you've learned:
In the previous Python packaging lessons, you learned:

Comment on lines +168 to +169
on GitHub actions is temporary, and users should not be getting the package from
here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on GitHub actions is temporary, and users should not be getting the package from
here.
on GitHub actions is temporary; users should not be getting the package from here.

@mihaimaruseac
Copy link
Contributor

So far you've been just publishing from your laptop , but one day you accidentally copy paste your password into bluesky (or whatever lol) and someone swipes it before you delete it! Now they are using your cool thing to steal other people's credit cards, that's not good! We can make things easier for ourselves as well as avoiding a certain category of attacks by..."

Just an example, hopefully u know what I'm saying. Bonus points for using a real example too :)

This is cool example and I think a real world scenario just occurred recently. I'll investigate more before linking to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants