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

[META] OIDC federation roadmap for Warehouse #12465

Closed
woodruffw opened this issue Oct 31, 2022 · 23 comments
Closed

[META] OIDC federation roadmap for Warehouse #12465

woodruffw opened this issue Oct 31, 2022 · 23 comments
Assignees
Labels
meta Meta issues (rollouts, etc) trusted-publishing

Comments

@woodruffw
Copy link
Member

woodruffw commented Oct 31, 2022

This is meta-issue, tracking different strands of development/design for Warehouse's use of OIDC.

Goals

There are two high-level goals for Warehouse's OIDC work:

  1. Enable "OIDC macaroon minting" for a handful of CI providers, enabling users to configure trusted repositories via OIDC instead of manually provisioning API tokens
  2. Add support for an OIDC IdP to PyPI, allowing it to become its own identity provider for ecosystems like Sigstore

Task 2 is tracked separately under #12466. No longer planned.

Task 1: OIDC macaroon minting

This task has two subtasks: core OIDC support work, and individual support for each CI provider's OIDC IdP.

Core OIDC support work

The core work required for OIDC JWT consumption is tracked under https://github.com/pypi/warehouse/projects/4, and is almost entirely complete (but currently disabled via a feature flag). Some of the key work included additional models and services for OIDC state management, as well as a general refactor of Warehouse's AuthN/AuthZ layers to use Pyramid 2.0-style APIs.

Core refs:

GitHub OIDC macaroon minting

This is also tracked under https://github.com/pypi/warehouse/projects/4.

Core refs:

Once #11272 is merged, this will be functionally complete (but again, disabled via a feature flag).

One sidecar feature is OIDC tokens from reusable workflows. This is tracked in #11096.

Adjacent tasks

Separately from these two tasks, there are also separate issues that track usability/UX changes that the OIDC work would benefit from.

Core refs:


CircleCI trusted publishing

This is still in the planning phase.

Google trusted publishing

This is tracked under #13551.

GitLab trusted publishing

This is tracked under #13575.

@woodruffw woodruffw self-assigned this Oct 31, 2022
@woodruffw
Copy link
Member Author

cc @di for visibility.

@di di added the meta Meta issues (rollouts, etc) label Oct 31, 2022
@di
Copy link
Member

di commented Nov 2, 2022

Some follow-on things we'll need to do once this is merged/enabled:

@woodruffw
Copy link
Member Author

Other refs:

@woodruffw
Copy link
Member Author

Just as a reminder to myself: we probably also want to vary the OIDC audience by PyPI's FQDN, e.g. instead of pypi everywhere it should be pypi.org for the main PyPI instance and test.pypi.org for TestPyPI.

This should be easy to do, since we can grab the expected FQDN from warehouse.domain.

@di
Copy link
Member

di commented Mar 6, 2023

Just as a reminder to myself: we probably also want to vary the OIDC audience by PyPI's FQDN, e.g. instead of pypi everywhere it should be pypi.org for the main PyPI instance and test.pypi.org for TestPyPI.

We chatted about this and decided to stick with pypi/testpypi as audiences for PyPI and TestPyPI respectively because this removes the assumption of "one index per domain", which is currently true but might not be true in the future.

@woodruffw
Copy link
Member Author

See #13148 for another follow-up bugfix.

@di
Copy link
Member

di commented Mar 16, 2023

For anyone following along, you can sign up for the closed beta for this feature here: #12965 (comment).

@di
Copy link
Member

di commented Mar 29, 2023

Some additional prior art to consider here as we roll this out: pub.dev also supports OIDC-based publishing:

@woodruffw
Copy link
Member Author

Hmm, their model is interesting: rather than checking the workflow's filename, they only allow tag patterns and accept any workflow so long as it was triggered by a tag event (under the theory that only sufficiently privileged users can cut tags?).

If I'm right, that's a little weaker than our model (since any repo maintainer can cut tags by default, and anybody with commit access can modify a workflow). But the fact that they support tag patterns is a good sign that we should additionally support them 🙂

@di
Copy link
Member

di commented May 3, 2023

Looks like GitLab now supports a customizable aud claim: https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html

@woodruffw
Copy link
Member Author

For tracking: #13551 tracks support for Google Cloud as an OIDC provider, similar to GitHub.

@woodruffw
Copy link
Member Author

Opened #13575 as well, for GitLab support.

@GergelyKalmar
Copy link

Tag patterns would be a great addition to support. We typically kick off a publishing workflow on releases (which create new tags), so the branch-based environment protections are pretty useless. Using protected tags in those cases instead seems to be a better and more secure way to actually control access to PyPI publishing workflows.

@GergelyKalmar
Copy link

Actually in this case it's not even possible to sufficiently secure the PyPI publishing workflows currently. Any deployment branch rule will block the workflow from running when checked out at a tag, unless the branch rule matches the tag itself (e.g. v* seems to work for a tag like v1.7.0). However, this also allows committers to kick off a workflow from any branch that starts with a v, so that's a problem.

@woodruffw
Copy link
Member Author

Tag patterns would be a great addition to support.

Agreed! This was identified during the beta period as a useful addition, and it's on my feature backlog.

We typically kick off a publishing workflow on releases (which create new tags), so the branch-based environment protections are pretty useless. Using protected tags in those cases instead seems to be a better and more secure way to actually control access to PyPI publishing workflows.

To be clear: it's useless for your case.

That's fine and valid, but there are multiple ways to secure a workflow on GitHub; we started with environment names (and corresponding environment restrictions, like required reviewers) because they impose fewer idiomatic constraints on PyPI users: not everybody releases from a tag (much less a GitHub release), so tag patterns would have been confusing to users who e.g. run a locked-down release workflow manually from a commit once it's ready for release.

The current plan is to support tag patterns as an additional optional constraint, similar to how we added support for environments.

Actually in this case it's not even possible to sufficiently secure the PyPI publishing workflows currently.

Can you say more about your expectations here?

This is why we encourage users to set up required reviewers in their environment, if their threat model is an "untrusted committer" one: regardless of tag or other event source, a required reviewer setup forces a trusted user to manually approve or reject the publishing workflow below it actually runs.

You can see an example of that in action here: https://github.com/pypa/pip-audit/actions/runs/4884995570

@GergelyKalmar
Copy link

Of course, I meant it's not particularly useful in those cases where GitHub releases are used to trigger publishing. I don't doubt there's plenty of other equally viable approaches!

As far as I understood the idea behind environments was to restrict who is able to publish to PyPI, i.e. it's possible to set up restrictions where users with commit rights are unable to obtain an OIDC token to upload an unapproved package. This is because OIDC tokens can be restricted to specific workflows and environments, and environments can add further restrictions, e.g. restricting runs to only the main branch (where one can set up branch protection rules to require reviews for example).

When releasing via GitHub releases, this approach doesn't work because the deployment does not happen from a single branch, it happens from tags (hence the deployment branch rules are inapplicable). With the matching trick we can create a deployment branch rule to restrict runs to the v* "branches" (which are actually tags in this case), however, then anyone with a commit right can create a new branch called v-hack, obtain an OIDC token and push whatever they want to PyPI.

With protected tags we could ensure that only maintainers are able to publish a release. Of course, having a manual approval still works, but we often would prefer to use user roles to restrict who is able to release/publish (instead of adding the friction of manual workflow approvals).

@woodruffw
Copy link
Member Author

As far as I understood the idea behind environments was to restrict who is able to publish to PyPI, i.e. it's possible to set up restrictions where users with commit rights are unable to obtain an OIDC token to upload an unapproved package. This is because OIDC tokens can be restricted to specific workflows and environments, and environments can add further restrictions, e.g. restricting runs to only the main branch (where one can set up branch protection rules to require reviews for example).

Yep, that's the idea 🙂 -- an environment can include a specific list of people (or teams) that are allowed to run it, which means that someone has to manually approve the workflow (on GitHub's side) before an OIDC token is issued. For example, this is what that looks like on the pip-audit repository:

Screenshot 2023-05-05 at 11 52 09 AM

With protected tags we could ensure that only maintainers are able to publish a release. Of course, having a manual approval still works, but we often would prefer to use user roles to restrict who is able to release/publish (instead of adding the friction of manual workflow approvals).

Making sure I understand: the use case you'd like solved here is removing the manual approval step, right? And tag protections rather than environment protections enable that?

If so, that's perfectly reasonable, and something we want to support!

I can't promise an exact timeline for it, but it was raised during beta testing as well (we added environment support in response, as a starting point), but it's good to know that PyPI users want it and will benefit from it 🙂

@GergelyKalmar
Copy link

Yes, you understand it correctly, the idea is to remove the need for a manual approve step but still have tight control over who is allowed to publish.

It's more of a feeling but I don't like the idea of manual workflow approvals that much because it is a small out-of-context action (as opposed to doing a review of a PR and approving/declining it right away as part of that process). To me it inherently feels more vulnerable to fatigue attacks (e.g. someone triggering multiple valid approval requests in a relatively short amount of time in order to let a malicious execution slip through). A smooth release-based workflow seems more natural to me (maintainer approves a PR, merges it and creates a new release which automatically runs all necessary workflows in the background without having to think about them at all), but I also admit it's probably just a mostly irrational personal preference.

@di
Copy link
Member

di commented Jun 6, 2023

CircleCI now supports a customizable aud claim: https://circleci.com/docs/api/v2/index.html#tag/OIDC-Token-Management

@di
Copy link
Member

di commented Jun 7, 2023

I think I'm going to close this: with #13883 we've removed the feature flag for this, and we're tracking additional providers in #13551, #13575, and #13888.

Thanks everyone for your help rolling this out! 🎉

@di di closed this as completed Jun 7, 2023
@GergelyKalmar
Copy link

Is there a separate issue tracking the tag protection support feature that we discussed earlier?

@woodruffw
Copy link
Member Author

Is there a separate issue tracking the tag protection support feature that we discussed earlier?

Thanks for reminding me -- I'll check for one, but if there isn't then I'll file one.

@woodruffw
Copy link
Member Author

Thanks again for reminding me @GergelyKalmar; I've opened #13911 for tracking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
meta Meta issues (rollouts, etc) trusted-publishing
Projects
None yet
Development

No branches or pull requests

3 participants