-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add guides around trusted publishing
- Loading branch information
Showing
14 changed files
with
151 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
--- | ||
layout: default | ||
title: Trusted Publishing | ||
url: /trusted-publishing | ||
--- | ||
|
||
Trusted Publishing is a term for using OpenID Connect (OIDC) to exchange short-lived identity tokens between a trusted third-party service and RubyGems.org. | ||
This allows obtaining short-lived API tokens in an automated environment (such as CI) without having to store long-lived API tokens or username/password credentials. | ||
|
||
For a quickstart guide, see: | ||
|
||
- [Adding a trusted publisher to an existing gem]() | ||
- [Pushing a new gem with a trusted publisher]() | ||
|
||
## How it works | ||
|
||
Trusted publishing is a mechanism for uploading gems to PyPi without using long-lived secret credentials. | ||
|
||
You don't need to be an OIDC expert to use trusted publishing, but it's helpful to understand the basics of how it works. | ||
|
||
1. Certain platforms, such as GitHub Actions, are OIDC _identity providers_, meaning they can issue short-lived identity tokens that third parties can **strongly** verify came from the CI service (as well as the repository, workflow, and commit that triggered the build). | ||
1. Gems on RubyGems.org can be configured to trust particular configurations from particular providers, making that configuration a trusted publisher for that gem. | ||
1. Release automation (such as GitHub Actions) can exchange the identity token for a short-lived API token from RubyGems.org, provided the token matches any trusted publishers that have been configured on RubyGems.org. | ||
1. The API token can be used only to push to the gems that are configured to trust the publisher, and only for a short period of time. | ||
|
||
This mechanism has significant security & usability advantages compared to traditional authentication mechanisms: | ||
|
||
- **Usability**: trusted publishing does not require manually creating & storing API tokens from RubyGems.org. The only manual step is configuring the trusted publisher on RubyGems.org. | ||
- **Security**: RubyGems.org's normal API tokens are long-lived, meaning an attacker who obtains one can use it indefinitely. Trusted publishing tokens are short-lived, meaning they can only be used for a short period of time. | ||
|
||
## Further reading | ||
|
||
We highly reccomend checking out the excellent docs written by our friends over at PyPi for some more in-depth information on how Trusted Publishing works: | ||
|
||
- [PyPi: Security model and considerations](https://docs.pypi.org/trusted-publishers/security-model/) | ||
- [PyPi: Internals and Technical Details](https://docs.pypi.org/trusted-publishers/internals/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
layout: default | ||
title: Adding a trusted publisher to an existing gem | ||
url: /trusted-publishing/adding-a-publisher | ||
--- | ||
|
||
Adding a trusted publisher to a gem only requires a single setup step. | ||
|
||
On [your profile page](https://rubygems.org/), click the link to any gem you'd like to configure. | ||
|
||
![List of gems on a RubyGems.org profile](/images/trusted-publishing/profile-gem-list.png){:class="t-img"} | ||
|
||
If you're a gem owner, you'll see a link to "Trusted publishers" on the right side of the page. Click that link. | ||
|
||
![Links shown on the sidebar of a gem page when the user is an owner](/images/trusted-publishing/gem-owner-sidebar-links.png){:class="t-img t-img--small"} | ||
|
||
This will take you to the gem's trusted publishers page. | ||
|
||
![Gem's trusted publisher page with a create button](/images/trusted-publishing/rubygem-trusted-publisher-create.png){:class="t-img"} | ||
|
||
Click the "Create" button, which will take you to the publisher configuration page. | ||
|
||
![Gem trusted publisher creation form](/images/trusted-publishing/rubygem-trusted-publisher-form.png){:class="t-img"} | ||
|
||
To enable trusted publishing for this gem, you'll need to tell RubyGems.org how to trust it. | ||
GitHub Actions (the only currently supported trusted publisher) requires the repository owner's name, repository name, and the name of the workflow that will be pushing the gem. | ||
|
||
Once you click "Create Rubygem trusted publisher", your publisher will be registered and will appear in the list of trusted publishers for this gem. | ||
|
||
![List of configured gem trusted publishers](/images/trusted-publishing/rubygem-trusted-publishers-index.png){:class="t-img"} | ||
|
||
Now, the `push.yml` workflow on `indirect/indirect-trusted-publishing` will be able to generate short-lived API tokens from RubyGems.org that are able to push to this gem. | ||
|
||
A publisher can be registered for multiple gems, and a gem can have multiple publishers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
--- | ||
layout: default | ||
title: Pushing a new gem with a trusted publisher | ||
url: /trusted-publishing/pushing-a-new-gem | ||
--- | ||
|
||
Trusted publishers are not just for existing gems, they can also be used to push new gems! | ||
|
||
This helps reduce the friction for setting up fully automated publishing workflows for new gems, | ||
since the same workflow will work for the first released version of a gem as well as all future versions. | ||
|
||
To set up a trusted publisher for a new gem, you'll need to set up a "pending" trusted publisher | ||
under your RubyGems.org profile. | ||
|
||
The process is the same as for [adding a trusted publisher to an existing gem](/trusted-publishing/adding-a-publisher), | ||
except that you'll also need to specify a gem name. | ||
|
||
To configure a pending trusted publisher, go to your [pending trusted publisher page](https://rubygems.org/profile/oidc/pending_trusted_publishers) | ||
|
||
![User's pending trusted publisher page with a create button](/images/trusted-publishing/pending-trusted-publisher-create.png){:class="t-img"} | ||
|
||
Click the "Create" button, which will take you to the publisher configuration page. | ||
|
||
![Pending trusted publisher creation form](/images/trusted-publishing/pending-trusted-publisher-form.png){:class="t-img"} | ||
|
||
For example, if you have a repository at `https://github.com/rubygems/sample-gem` with a release workflow at `push_gem.yml` and an environment named `release` that you would like to push to RubyGems.org as the `sample-gem` gem, you would enter the following values: | ||
|
||
![Pending trusted publisher creation form with values filled in](/images/trusted-publishing/pending-trusted-publisher-form-filled.png){:class="t-img"} | ||
|
||
Once you click "Create Pending trusted publisher", your publisher will be registered and will appear in the list of pending publishers for your account. | ||
|
||
![List of configured pending trusted publishers](/images/trusted-publishing/pending-trusted-publishers-index.png){:class="t-img"} | ||
|
||
From this point, the "pending" publisher will act like a "normal" publisher. | ||
After its first successful push, it will be converted to a "normal" trusted publisher for the new gem, | ||
and you will be added as the owner of the gem. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
layout: default | ||
title: Releasing gems with a trusted publisher | ||
url: /trusted-publishing/releasing-gems | ||
--- | ||
|
||
Once you have a trusted publisher configured, you can use RubyGems' [`configure-rubygems-credentials`](https://github.com/rubygems/configure-rubygems-credentials) GitHub Action to set up your workflow to push gems to RubyGems.org. | ||
|
||
This looks almost exactly the same as normal, except that you don't need any explicit usernames, passwords, or API tokens: GitHub's OIDC identity provider will take care of everything for you: | ||
|
||
```yaml | ||
jobs: | ||
push: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
id-token: write | ||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v4 | ||
- name: Set up Ruby | ||
uses: ruby/setup-ruby@v1 | ||
with: | ||
bundler-cache: true | ||
ruby-version: 3.2.2 | ||
- name: Configure RubyGems credentials | ||
uses: rubygems/configure-rubygems-credentials@segiddins/support-trusted-publishers | ||
- name: Set remote URL | ||
run: | | ||
git config --global user.email "$(git log -1 --pretty=format:'%ae')" | ||
git config --global user.name "$(git log -1 --pretty=format:'%an')" | ||
git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY" | ||
- name: Release | ||
run: bundle exec rake release | ||
``` | ||
Note the `id-token: write`` permission: you **must** provide this permission at either the job level (strongly recommended) or workflow level (discouraged). Without it, the publishing action won't have sufficient permissions to identify itself to RubyGems.org. |