Open sormuras opened 1 year ago
I can take a look.
Note to myself: update the TODO in the initial description
Next: I was waiting for some pull requests in sigstore-java to be merged first. Some of them are!
For example
@vlsi what do you think? Is about the right time to use the Gradle plugin to sign JUnit's artifacts in addition to the current PGP workflow?
A critical PR is
otherwise the generated bundle is just invalid as it misses signature
field.
That would be pretty good, however, you'll need to update sigstore-java
every time Fulcio/Rekor certificates change.
Automatic fetching of certificates is tracked in
Thanks for the quick reply, Vladimir!
Updating the status of this issue accordingly.
Wondering whether we can achieve the same effect (meaning, sign all JAR files) by using some GitHub Action after the build produced them? 🤔
Something similar to: https://github.com/junit-team/junit5/blob/700c2d4f25b48bfc4970f99d3198af5e8c5e3f37/.github/workflows/main.yml#L68
Of course, you can sign all the jars, poms, and other files via Action.
Here's the way you can generate signatures: https://github.com/sigstore/protobuf-specs/blob/16541696de137c6281d66d075a4924d9bbd181ff/java/scripts/sign_and_bundle_release.sh#L72
Just in case, the most secure approach would be signing the files within a separate GitHub workflow, so only well-known binaries have access to signing credentials (e.g. OIDC token).
In other words:
1) Prepare release files, and export them via "upload-artifacts" action or something like that 2) Sign them in a separate workflow 3) Collect all the signed files and publish them (e.g. push to Nexus)
I am afraid that sounds like a non-trivial GitHub Actions exercise. However, I consider the above Gradle plugin as a quick win for those who want to start signing without creating complicated workflows.
One more thing: there's https://github.com/slsa-framework/slsa-github-generator effort to come up with a reusable workflow for creating the attestations.
Something similar to: https://github.com/junit-team/junit5/blob/700c2d4f25b48bfc4970f99d3198af5e8c5e3f37/.github/workflows/main.yml#L68
The sad thing is that you launch Gradle with all the third-party plugins with Sonatype credentials. In the ideal world, we would like to expose credentials to a tiny tool that pushes code to Central only. That would reduce the attack surface. However, it sounds like it makes all "Gradle release plugins" unnecessary. Frankly speaking, that is slightly disappointing since I like how many tasks are easier to manage in Gradle rather than in bash scripts.
Recently GitHub improved "reusable workflows" part, so it might be that there's a possibility to come up with a reusable workflow that you just copy&paste and get "safe and secure" sign&push to Central.
With https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/ we can achieve artitfact attestations by calling https://github.com/actions/attest-build-provenance for all our artifacts just before deployment. No build tool plugin is required - updating the issue title accordingly.
@sormuras With #3846 merged, can we consider this done for now?
I was just about to add these items to the description:
TODO
But those could also go into dedicated issues.
I think adding them to this issue is fine. I was just wondering what's left to do, if anything.
Delete attestations generated by pull requests
In practice, you don't want allowing id-token: write
for pull request builds as they might generate attestations that look like "produced by junit-team".
https://github.com/sigstore-conformance/extremely-dangerous-public-oidc-beacon exists exactly for the reason of avoiding id-token: write
for PR builds and still having a valid OIDC token for the test purposes.
At the same time, you probably want to attest the generated pom files as well
In practice, you don't want allowing
id-token: write
for pull request builds [...]
Good to learn. Is there another way to guard against that? Like having a dedicated workflow build for attestation that only runs on behalf of the "junit-team"? Doesn't the following line already take care about that?
At the same time, you probably want to attest the generated pom files as well
We'll start with JAR files for the time being. Otherwise, why stop with pom files and not include hash files, Gradle modules files, etc. Mind that every type is multiplied with 19 ... the number of published packages by the JUnit 5 project.
As soon as Sonatype permits us to drop PGP/GPG for deployments to Maven Central and uses Sigstore-based attestations instead, we should consider generating attests for every and each file.
include hash files
The attestations attest hash of the file, so creating separate attestations for hash files sounds wasteful, and it adds no value.
The same goes for PGP: you don't generate PGP signatures for .sha1
filles.
By the way, both PGP and Sigstore are cryptographic signatures, so cross-signing makes no sense.
As soon as Sonatype permits us to drop PGP/GPG for deployments to Maven Central and uses Sigstore-based attestations instead, we should consider generating attests for every and each file
I would suggest you keep publishing both PGP and Sigstore for backward compatibility reasons. There are clients that verify PGP signatures for their dependencies, and removing PGP would be a step backwards.
Gradle modules files
There's a cyclic dependency when signing metadata.
Doesn't the following line already take care about that?
Having if branch==main
is good, however, keep in mind you still execute full Gradle build with all its dependencies, and every bit of it has access to id-token.
At the same time, if you add id-token: write
for the trusted branches only, then you do not need to "delete attestations generated by PRs".
In the ideal world, we execute build without id-token: write
privileges, and then execute attestation for the generated files. Then only attestation step would have access to the token.
I've raised https://github.com/actions/attest-build-provenance/issues/103 to check the indented usage with respect to security.
As soon as Sonatype permits us to drop PGP/GPG for deployments to Maven Central
As far as I know, Maven Central already supports uploading .sigstore.json
files without the corresponding .asc
PGP signatures. It does not validate the contents, however, it recognizes .sigstore.json
is cryptographic enough to not require PGP.
For instance, see check out .sigstore.json
files at https://repo1.maven.org/maven2/dev/sigstore/sigstore-java/0.10.0/
Generate verify-able signed attestations for every artifact made with GitHub Actions.
Attestations do appear here:
TODO
id-token: write
for pull request buildsSNAPSHOT
JAR files to include the current git commit hash, likejunit-jupiter-5.11.0-SNAPSHOT+d8697a0.jar
for https://github.com/junit-team/junit5/attestations/1002406