I'm developing an open source project and I have been working on making the builds reproducible so that my users can compare the checksums of the binaries that I distribute with their own builds (if they were to build the project with/from the source code).
Unfortunately, new versions of Windows and MacOS use code signing in order to check binaries and prevent their execution if they aren't signed (I'm aware that there are ways to override this and execute the binary anyways, but this is not user friendly).
I'd like to sign the binaries that I distribute so that my users can run them without any problems. But I'm not sure if that is possible to do while also keeping the reproducible builds.
For a build to be reproducible, the end user must have all the tools / source code required to build the project and, once compiled, the end result should be the same bit-a-bit binary compared to the one that I'm distributing. But that would mean that I'd have to distribute the private key / cert used to sign the binary, which is not a good idea for multiple reasons.
Is there a way to have both reproducible builds and signed binaries?
Here is a general approach for creating reproducible signed builds for open source.
Create your "sign binaries" script as follows:
SIGNING_CHECKSUMIf there is a match:
SIGNING_SIGNATUREto build the packageSIGNING_SIGNATUREwas signed bySIGNING_PUBLIC_KEYIf there is not a match:
SIGNING_CHECKSUMSIGNING_SIGNATURESIGNING_SIGNATUREwas signed bySIGNING_PUBLIC_KEYEnd result is that anybody can reproducibly build the untampered source code. Anybody can edit the source code and reproducibly build the binary so long as the modifications to not modify the signing preimage. And only the developer with access to the signing key is able to sign new releases.