Back to help contents

Deterministic build process

This is a technical article that assumes a detailed knowledge of Java build processes.

The reason for having a deterministic build process is to ensure that others can independently verify that the code has not been tampered with. This is accomplished through a combination of:

Co-signing a release

Here is a run-through of the overall process. Following the usual crypto casting, the lead developer is Alice, with Charles and Claire as co-signers:

  1. Alice does the final release build from git master using agreed JDK
  2. Alice takes a SHA256 of each artifact (by running a simple shared script) and adds it to release-notes.txt
  3. Alice adds any extra text (version and whatnot) then does a GPG-sign with the MultiBit key and pushes to the master branch
  4. Charles performs a rebuild and verifies the SHA256 of each artifact (using an external tool such as OpenSSL/shasum etc)
  5. Claire does the same as Charles
  6. Charles and Claire report any problems to Alice
  7. If all is OK, Alice Alice performs an OS-specific code sign and uses the JAR in install4j
  8. Alice GPG-signs the installer with the MultiBit key
  9. Charles verifies the release notes and verifies that the installer delivers the correct JAR to the end user
  10. Charles signs the release-notes.txt with his GPG key and pushes that to master (or issues a pull request)
  11. Claire does the same as Charles with a further updated release-notes.txt
  12. After all co-signers have signed, Alice releases the installer to the live site

Verifying an OS-specific signed JAR

In order to run without warnings on Windows and OS X it is necessary to supply an installer that has been signed with an OS-specific code signing key. This is tied to a particular developer's identity and is verified by the issuing authority (such as Microsoft or Apple). Linux does not use code signing in this way due to the lack of a central owning authority.

Both Microsoft and Apple provide tools to enable developers to verify the before and after state of a code-signed artifact without requiring ownership of the signing keys themselves. This allows the original artifact to be extracted from the signed version and a hash performed to ensure it matches the one built locally.

Related articles

Here are some related articles:

Back to help contents