-
Notifications
You must be signed in to change notification settings - Fork 1k
Trusted publishing: Support for GitHub reusable workflows #11096
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
Comments
Just as a note: this will have to interoperate with #11263. |
Any chance to expedite this issue? It seems there's many who would be eager to move over to trusted publishing now that it is the recommended approach, but not being able to do the flow from a reusable workflow is a pretty major blocker. This issue also does not seem to be documented anywhere so we only find out about it once we changed everything to use the new approach. |
I can't personally promise a timeline here, but it is on my backlog of things to do.
Thank you for pointing this out; I'll make some changes to the docs to emphasize that reusable workflows are not currently supported. |
I've opened #13592 for this. Thanks again for bringing it to our attention! |
This reverts commit d4e6137. Blocked by pypi/warehouse#11096.
This reverts commit f23a477. Blocked by pypi/warehouse#11096.
Switch to using API Token pending pypi/warehouse#11096
@woodruffw I just stumbled upon an example of a reusable workflow actually working with OIDC here jorisroovers/gitlint#486 — could you confirm this is because of |
That workflow is in the same repository though, I think the issue is with reusable workflows that are in a different repository (e.g. in a separate public repo). |
Yeah, I think that's because it's in the same repo, not because of In other words: reusable workflows do work with the current implementation, just not reusable workflows that are external to the repository that the trusted publisher was configured with. |
Yes, you can't use |
You can get around the |
I also wonder if it's possible to do something like secrets:
GITHUB_TOKEN: ${{ github.token }} to make OIDC in the reusable workflow pretend to be the called workflow... |
Currently does not work with reusable workflows, e.g. release-nightly.yml calling release.yml Ref: https://github.com/pypa/gh-action-pypi-publish/releases/tag/v1.11.0 pypa/gh-action-pypi-publish#255 pypi/warehouse#11096 Authored by: bashonly
Unable to use reusable workflow with trusted publishing pypi/warehouse#11096 Using trusted publishing in a composite action is also not supported https://github.com/marketplace/actions/pypi-publish#non-goals
Unable to use reusable workflow with trusted publishing pypi/warehouse#11096 Using trusted publishing in a composite action is also not supported https://github.com/marketplace/actions/pypi-publish#non-goals
Unable to use reusable workflow with trusted publishing pypi/warehouse#11096 Using trusted publishing in a composite action is also not supported https://github.com/marketplace/actions/pypi-publish#non-goals
Unable to use reusable workflow with trusted publishing pypi/warehouse#11096 Using trusted publishing in a composite action is also not supported https://github.com/marketplace/actions/pypi-publish#non-goals
It sounds like the progress here is going in a direction that's not going to help me (and thus trusted publishing will be out of reach indefinitely). I've developed a system for managing software with the value proposition being that one can maintain packages without having to copy/paste the system-wide configuration (CI config) to each project. So the project uses a minimal project-repo-level config (example) that links into a system-wide config that includes the release hook. So when something needs to change at the system level (such as it has several times in the past few months), those changes automatically reflect in the enrolled repos. It wouldn't be suitable for these repos to pin to the shared workflow, because that would defeat the purpose of streamlining the maintenance and would require a commit to each of hundreds of repos each time the system definition needed a tweak. Do I understand correctly that the planned support for trusted repos for reusable workflows is going to require that the reusable workflow be pinned, and thus won't be suitable for the coherent system? |
I don't think the plan is to require a pin on the reusable workflow, no -- that's been floated as an idea for additionally constraining the Trusted Publisher (and asserting its hermetic properties), but the basic idea laid out in #11096 (comment) would allow reusable workflows to be configured without a pin, like normal workflow identities currently can be. |
For Ruby I ended up implementing a composite action: https://github.com/voxpupuli/ruby-release. This works because a composite action doesn't create a new context and you can generate an OIDC token. |
@ekohl it's important to physically separate jobs that build things from the job that publishes them. This is because giving elevated privileges to all the transitive deps in the build tool chain is usually a bad idea. Allowing OIDC in other contexts can lead to repo identity impersonation in systems beyond PyPI, which is why I've been actively discouraging that. And additionally, when we were optimizing the action, it ended up being a composite action wrapping a docker one. It turned out that GH doesn't work well with nested composite actions and various unexpected context leak into our env making it defunct. So I've been trying to heavily narrow down the scope of what's considered supported in the action: https://github.com/marketplace/actions/pypi-publish#Non-goals. That said, I'm planning to make a reusable workflow under PyPA that people would be able to use w/o having to duplicate that within each of their projects. It wouldn't work until PyPI supports this, so I'm not in a hurry to start that just yet. But that workflow will implement what I consider secure practices, so others wouldn't have to think about it and only bring in their jobs that build their dists. |
In my Ruby workflow I use plain You can argue that I end up installing |
I don't know Ruby enough, but it sounds similar to what PEP 517 build backends do. Hence, the same precautions apply. In the reusable workflow I'm thinking of, there'd be exactly 2 tasks — one to download pre-built dists and the second one to upload them. And nothing else, even remotely untrusted. |
Due to pypi/warehouse#11096 one cannot use a reusable workflow for uploading wheels to PyPI yet.
Due to pypi/warehouse#11096 one cannot use a reusable workflow for uploading wheels to PyPI yet.
TL;DR: `job_workflow_ref` and `workflow_ref` are *often* the same thing and have the same value, but sometimes diverge in ways that make later support for GitHub's reusable workflows difficult. This guide should recommend `workflow_ref` instead of `job_workflow_ref` for the "baseline" of Trusted Publishing, since it's always correct as the "initiating" workflow identity. See pypi/warehouse#11096 and rust-lang/crates.io#11131 (comment) for more context. Signed-off-by: William Woodruff <[email protected]>
TL;DR: `job_workflow_ref` and `workflow_ref` are *often* the same thing and have the same value, but sometimes diverge in ways that make later support for GitHub's reusable workflows difficult. This guide should recommend `workflow_ref` instead of `job_workflow_ref` for the "baseline" of Trusted Publishing, since it's always correct as the "initiating" workflow identity. See pypi/warehouse#11096 and rust-lang/crates.io#11131 (comment) for more context. Signed-off-by: William Woodruff <[email protected]>
Following IRL discussion with @miketheman , @webknjaz and @woodruffw , here's pseudocode for a potential migration path that adds support for publishing from a (top-level) workflow file that calls another (reusable) workflow file. claim_top = "workflow_ref"
claim_bottom = "job_workflow_ref"
reusable_workflow_supported_date = "TBD" # date when this change is merged
if claim_top == claim_bottom: # non-reusable workflow case
tp_obj = query(TP, TP.filename == claim_top)
if tp_obj:
# exchange token
pass
else:
raise TPNotFound()
if claim_top != claim_bottom: # reusable workflow case
# if claim_bottom != lastSecurityEvent.bottom: sendEmail()
# securityEvent.record(TP, claim_bottom)
tp_obj = query(TP, TP.filename == claim_top)
if tp_obj:
# logic for future support of constraining reusable workflow
# if tp_obj.bottom_filename is None:
# # send email (optional)
# # exchange token
# pass
# elif tp_obj.bottom_filename == claim_bottom: # bottom_filename is an optional field
# # exchange token
# pass
# elif tp_obj.bottom_filename != claim_bottom:
# raise TPNotFound()
# exchange token
pass
else:
# temporary support for migration purposes
tp_obj_bottom = query(TP, TP.filename == claim_bottom AND TP.created_date < reusable_workflow_supported_date)
if not tp_obj_bottom:
raise TPNotFound()
else:
# exchange token
# send email about TP referring to reusable instead of top-level workflow
pass |
Our MVP implementation (#10753) assumes that the workflow is in the same repository, which is not necessarily true.
We should support reusable workflows, specifically via the
job_workflow_ref
claim.The text was updated successfully, but these errors were encountered: