-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Sign docker images using github attestations #8685
Conversation
fd48d69
to
5abc4eb
Compare
A word of warning: I am not 100% certain I fully understand everything that the |
cc @samypr100 (as always, no obligation) |
5abc4eb
to
d1a3809
Compare
d1a3809
to
2872b9a
Compare
2872b9a
to
9b162d3
Compare
Note, I'm running a release job on my fork with these changes (9b162d) as I'd like to see it working E2E https://github.com/samypr100/uv/actions/runs/11593512252 |
@mjpieters signed images are here https://github.com/samypr100/uv/pkgs/container/uv in case you'd like to verify the signatures are working as expected |
9b162d3
to
4a278c1
Compare
Excellent! I was working my way through understanding cargo dist in my own fork to try this out but hadn't gotten as far as actually seeing the workflow complete. The first thing I notice is that the the .sig files are now obscuring the actual docker images on that page, which is a bummer. The signatures are valid however!
I'll have to see what can be done about those signature files in the registry. |
So cosign pushes the signature as a new 'container' to the registry, tagged with I've looked at a number of other projects that use cosign to sign their containers (of which there are a very large number), and all the ones I looked at so far show these tags at the top. E.g. the Dependabot update bundler (a Github project!) has signature tags at the top. You see this on other registries too, e.g. the boxyhq jackson container on the docker hub. I see but a few options here:
|
We're already pushing the |
You push not only a tag, but a manifest as well. You'd have to separate the two steps; push the manifest without tags and then tag the digest of the manifest afterwards. It could be that you can retag the same digest; I'll try this out in my own fork registry. |
I think the main issue here is how GH ranks packages and gives no control over the ordering to orgs/users of what's displayed, so we have to rely on these ordering hacks related to publishing. |
and from my experiments it is clear that it is order that the manifest were pushed to the registry that is used to list them. I tried deleting then restoring, and retagging (moving tags to another manifest then back again to the right manifest), and nothing shifts the signature from the top. So the only thing that would work is to build and not push, sign (and let cosign push the signature manifest), and only then push the actual image manifest. |
# PRs from forks don't have access to secrets, disable this step in that case. | ||
if: ${{ github.event.pull_request.head.repo.full_name == 'astral-sh/uv' }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this in here so this workflow would at least build the docker image in this PR. The jobs otherwise would just fail with a Password required error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, I think there's 3 other places in this file missing this conditional (if we're in favor of adding it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think there was any point as those 3 all are part of jobs that only run on release.
1d03cda
to
59afb8e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I might wait for @samypr100 to give it a look too.
# PRs from forks don't have access to secrets, disable this step in that case. | ||
if: ${{ github.event.pull_request.head.repo.full_name == 'astral-sh/uv' }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, I think there's 3 other places in this file missing this conditional (if we're in favor of adding it)
Good news is that this approach does keep the tags working as-is. I tried it on a test run here https://github.com/samypr100/uv/actions/runs/13066181068 Which did keep the package versions tags intact https://github.com/samypr100/uv/pkgs/container/uv Verifications also work! $ gh attestation verify --owner samypr100 oci://ghcr.io/samypr100/uv:latest [23:14:17]
Loaded digest sha256:ebd769519134c730eb1af61ddd06a8f5629f5082d0c2d8f02a6d577fe4b2a9dc for oci://ghcr.io/samypr100/uv:latest
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:ebd769519134c730eb1af61ddd06a8f5629f5082d0c2d8f02a6d577fe4b2a9dc was attested by:
REPO PREDICATE_TYPE WORKFLOW
samypr100/uv https://slsa.dev/provenance/v1 .github/workflows/build-docker.yml@refs/heads/cosign-docker-images
$ gh attestation verify --owner samypr100 oci://ghcr.io/samypr100/uv:0.5.26 [23:14:23]
Loaded digest sha256:ebd769519134c730eb1af61ddd06a8f5629f5082d0c2d8f02a6d577fe4b2a9dc for oci://ghcr.io/samypr100/uv:0.5.26
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:ebd769519134c730eb1af61ddd06a8f5629f5082d0c2d8f02a6d577fe4b2a9dc was attested by:
REPO PREDICATE_TYPE WORKFLOW
samypr100/uv https://slsa.dev/provenance/v1 .github/workflows/build-docker.yml@refs/heads/cosign-docker-images
$ gh attestation verify --owner samypr100 oci://ghcr.io/samypr100/uv:0.5 [23:14:27]
Loaded digest sha256:ebd769519134c730eb1af61ddd06a8f5629f5082d0c2d8f02a6d577fe4b2a9dc for oci://ghcr.io/samypr100/uv:0.5
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:ebd769519134c730eb1af61ddd06a8f5629f5082d0c2d8f02a6d577fe4b2a9dc was attested by:
REPO PREDICATE_TYPE WORKFLOW
samypr100/uv https://slsa.dev/provenance/v1 .github/workflows/build-docker.yml@refs/heads/cosign-docker-images
$ gh attestation verify --owner samypr100 oci://ghcr.io/samypr100/uv:python3.13-bookworm [23:14:41]
Loaded digest sha256:5537896c0c8bd2351350d32dea35c590997c418e954fb5b31d6fcbfd96126562 for oci://ghcr.io/samypr100/uv:python3.13-bookworm
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:5537896c0c8bd2351350d32dea35c590997c418e954fb5b31d6fcbfd96126562 was attested by:
REPO PREDICATE_TYPE WORKFLOW
samypr100/uv https://slsa.dev/provenance/v1 .github/workflows/build-docker.yml@refs/heads/cosign-docker-images
... |
cosign uses the GitHub action ID token to retrieve an ephemeral code signing certificate from Fulcio, and store the signature in the Rekor transparency log.
59afb8e
to
04398a4
Compare
Would you mind following with a brief guide on how to verify images in https://docs.astral.sh/uv/guides/integration/docker/ ? |
I'll see what I can do! |
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.5.25` -> `0.5.27` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>astral-sh/uv (astral-sh/uv)</summary> ### [`v0.5.27`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0527) [Compare Source](astral-sh/uv@0.5.26...0.5.27) ##### Enhancements - Avoid setting permissions during tar extraction ([#​11191](astral-sh/uv#11191)) - Remove warnings for missing lower bounds ([#​11195](astral-sh/uv#11195)) - Update PubGrub to set-based outdated priority tracking ([#​11169](astral-sh/uv#11169)) - Improve error messages for `uv pip install` with `--extra` or `--all-extras` and invalid sources ([#​11193](astral-sh/uv#11193)) - Sign Docker images using GitHub attestations ([#​8685](astral-sh/uv#8685)) ##### Preview features - Don't expand self-referential extras in the build backend ([#​11142](astral-sh/uv#11142)) ##### Performance - Filter discovered Python executables by source before querying ([#​11143](astral-sh/uv#11143)) - Optimize exclusion computation for markers ([#​11158](astral-sh/uv#11158)) - Use Astral-maintained `tokio-tar` fork ([#​11174](astral-sh/uv#11174)) - Remove unneeded `.clone()` ([#​11127](astral-sh/uv#11127)) ##### Bug fixes - Fix relative paths in bytecode compilation ([#​11177](astral-sh/uv#11177)) - Percent-decode URLs in canonical comparisons ([#​11088](astral-sh/uv#11088)) - Respect concurrency limits in parallel index fetch ([#​11182](astral-sh/uv#11182)) - Use wire JSON schema for conflict items ([#​11196](astral-sh/uv#11196)) - Use explicit `_GLibCVersion` tuple in uv-python crate ([#​11122](astral-sh/uv#11122)) ##### Documentation - Add Git SHA locking behavior to docs ([#​11125](astral-sh/uv#11125)) - Add best-practice flags to `pip install` example in troubleshooting guide ([#​11194](astral-sh/uv#11194)) - Set `VIRTUAL_ENV` in Jupyter kernels ([#​11155](astral-sh/uv#11155)) - Add instructions for deactivating an environment ([#​11200](astral-sh/uv#11200)) ### [`v0.5.26`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0526) [Compare Source](astral-sh/uv@0.5.25...0.5.26) ##### Enhancements - Add support for `uvx python` ([#​11076](astral-sh/uv#11076)) - Allow `--no-dev --invert` in `uv tree` ([#​11068](astral-sh/uv#11068)) - Update `uv python install --reinstall` to reinstall all previous versions ([#​11072](astral-sh/uv#11072)) - Consistently write log messages with capitalized first word ([#​11111](astral-sh/uv#11111)) - Suggest `--build-backend` when `--backend` is passed to `uv init` ([#​10958](astral-sh/uv#10958)) - Improve retry trace message ([#​11108](astral-sh/uv#11108)) ##### Performance - Remove unnecessary UTF-8 conversion in hash parsing ([#​11110](astral-sh/uv#11110)) ##### Bug fixes - Ignore non-hash fragments in HTML API responses ([#​11107](astral-sh/uv#11107)) - Avoid resolving symbolic links when querying Python interpreters ([#​11083](astral-sh/uv#11083)) - Avoid sharing state between universal and non-universal resolves ([#​11051](astral-sh/uv#11051)) - Error when `--script` is passing a non-PEP 723 script ([#​11118](astral-sh/uv#11118)) - Make metadata deserialization failures non-fatal in the cache ([#​11105](astral-sh/uv#11105)) - Mark metadata as dynamic when reading from built wheel cache ([#​11046](astral-sh/uv#11046)) - Propagate credentials for `<index>/simple` to `<index>/...` endpoints ([#​11074](astral-sh/uv#11074)) - Fix conflicting extra bug during `uv sync` ([#​11075](astral-sh/uv#11075)) ##### Documentation - Add PyTorch XPU instructions to the PyTorch guide ([#​11109](astral-sh/uv#11109)) - Add docs for signal handling ([#​11041](astral-sh/uv#11041)) - Explain build frontend vs. build backend ([#​11094](astral-sh/uv#11094)) - Fix formatting of `RUST_LOG` documentation ([#​10053](astral-sh/uv#10053)) - Fix typo in `--no-deps` description ([#​11073](astral-sh/uv#11073)) - Reflow CLI documentation comments ([#​11040](astral-sh/uv#11040)) - Shorten "Using existing Python versions" nav item so it fits on one line ([#​11077](astral-sh/uv#11077)) - Some minor touch-ups to the Python install guide ([#​11116](astral-sh/uv#11116)) - Update Dependabot tracking issue link ([#​11054](astral-sh/uv#11054)) - Update documentation for running in a container ([#​11052](astral-sh/uv#11052)) - Upgrade PyTorch version in documentation ([#​11114](astral-sh/uv#11114)) - Use `sys_platform` in lieu of `platform_system` in PyTorch docs ([#​11113](astral-sh/uv#11113)) - Use positive (rather than negative) markers in PyTorch examples ([#​11112](astral-sh/uv#11112)) - Fix unnecessary backslashes in brackets ([#​11059](astral-sh/uv#11059)) - Suggest setting copy link mode in GitLab integration guide ([#​11067](astral-sh/uv#11067)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNDMuMCIsInVwZGF0ZWRJblZlciI6IjM5LjE1Ni4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
As [requested by @zanieb](#8685 (comment)).
GitHub attestation signing uses the GitHub action ID token to retrieve an ephemeral code signing certificate from Fulcio, and store the signature in the Rekor transparency log.
Once an image has been successfully signed, you should be able to verify the signature with:
Closes #8670