I’m trying to verify the signatures on the recent Hipparchus release, but the jars from packages.orekit.org fail to validate. The signatures on maven central are valid.
gpg: WARNING: no command supplied. Trying to guess what you mean ...
gpg: assuming signed data in 'hipparchus-ode-4.0.1.jar'
gpg: Signature made Fri 21 Mar 2025 01:28:23 PM EDT
gpg: using RSA key 12D16069219C90212A974D119AE296FD02E9F65B
gpg: BAD signature from "Luc Maisonobe (CODE SIGNING KEY) <luc@apache.org>" [unknown]
Looking closer the jar files on maven central are different from the ones in packages.orekit.org, but the asc files are the same. SHA1 for packages.orekit.org:
So which jar is the Hipparchus 4.0.1 release? Should the asc files on packages.orekit.org be updated to match maven central? CC @luc since his key is involved.
I have no idea about what went wrong!
There was a strange problem with 4.0 (the staging repository disappeared before release), but nothing strange occurred for 4.0.1 as far as I remember.
There is something I don’t understand.
How does packages.orekit.org get the signatures? Does it download from sonatype or does it build the packages by itself from the CI?
If it downloads, it should have the same files and signatures as sonatype. If it build, it should not even have signatures because they require the private key to generate.
If I’m not mistaken, the Hipparchus packages are only pushed to the Sonatype repository when the release profile is used. This is what the script release.sh does:
I therefore conclude that the packages being pushed onto the two repositories are not the same, but rather two different packages from two different builds made in two different contexts.
It is not surprising that they do not have the same checksum, but the accompanying signature should be different.
It is a process that can be improved…
Yes. In fact I do generally not use the script but runs the command lines one by one, following the release guide. And it is during these steps that at some point I have to provide the signature private key.
Yes. I think this is correct as long as we are dealing with unsigned snapshot artifacts, but should probably not be done with official release. And in any case, the signatures from the released artifacts should not be copied from Sonatype, and I guess the only way they can get in our repository is if they are imported.
Another possibility would be to sign the artifacts automatically when we build them in the CI, probably using specific keys for that (distinct from release keys). I think some projects do automated signing, but to be honest I always found it scary as to me it implies some private keys are lying around unencrypted in an (hopefully secured) computer.
I share your concern, but there are probably strategies that can be used to make the process safer and build a little confidence. I would need to do some research and look at what projects such as SLSA are proposing.
@evan.ward, the CI/CD pipeline publishes the artifacts in the maven-releases repository and not in the maven-public repository:
But there is no GnuPG signature file in the maven-release repository.
I don’t fully understand what this maven-public repository is on our Nexus instance (it’s one of the few components of the infrastructure that I haven’t deployed and configured). It seems to be a repository cache.
@gbonnefille explained to me what the maven-public repository was and why we were getting the strange result that @evan.ward had noticed.
maven-releases is our local Maven repository where the official Orekit releases are published
maven-snapshots is our local Maven repository where the Orekit snapshots are published
maven-central is a proxy to the official Maven Central repository
maven-public is neither a local repository nor a proxy, but a “group”, i.e. a pseudo-repository providing a unified view of a set of repositories. In the present case, the repositories associated with the group are, in this order:
maven-releases
maven-snapshots
maven-central
When an artifact is searched for in the maven-public repository, Nexus first searches for it in maven-releases, then in maven-snapshots, then in maven-central. This is why this repository associates the hipparchus-ode-4.0.1.jar artifact published in maven-release with the artifact hipparchus-ode-4.0.1.jar.asc published in maven-central.
It’s misleading, but it reassures me that no repository has been compromised.
Now, the following questions remain:
The motivation of the maven-public repository: Who uses it? Why?
If the order of the artifacts is correct: Wouldn’t it be more relevant to start searching for them in maven-central?
And, beyond these considerations, how can the Hipparchus publication workflow be improved?
It seems to me that for a given release, we should only publish one artifact (the one pushed into Nexus, because it has successfully passed all the CI/CD tests). This artifact should then be retrieved by a release manager to generate the cryptographic signature. This signature should then be pushed to our maven-release repository, and then both (artifact and signature) should be pushed to the official Maven Central repository.
I don’t know if these operations can be performed with Maven. Maybe a small dedicated Shell script is needed…
But in any case, it seems to me that it would be advisable to have a single source of truth; you can’t publish two different files for a single official version. At a time when securing the supply chain is becoming obvious to everyone, it would seem wise to examine Hipparchus’s current process and question it.
I don’t know how to do that. In order to publish to maven central, we currently use the nexus-staging-maven-plugin configured to send directly to SonaType. It seems to me that they are changing their publishing process as the header at OSSRH tells this service will be decommissioned end of June and that people should switche to central portal. We have to investigate this and see if we can or should have an intermediate nexus instance.
In any case, I agree we should improve the process and have stricter behavior that users can rely on.
Sébastien, that’s a great investigation. Glad you figured it out.
One solution could be to remove maven-releases from the maven-public group. That way maven-public would use central for the releases and the local hosted repository for snapshots.
In Orekit the maven-public group is used in .CI/maven-settings.xml.