Collaborative Working Sessions - Born reproducible III

Follow up of Born Reproducible II

In this session, we were more concrete. We came up with how each step in the framework in part II could be implemented for Java (especially maven) ecosystem.

Reference Implementation

Step 0

Assume that the clean environment is the GitHub action runner. Although you have more control on your system, the information you care about (like java version, mvn version) is know in GitHub action runner as well.

Step 1

  • Inputs:
    1. Java source code
    2. Build configuration (pom.xml): Try to have a minimal working version of that. Remove all the unecessary boilerplate code.
  • Outputs:
    1. all the jars and the SBOMs produced as the build output.

    .buildspec in the reference implementation documents all of this.

Step 2

Build metadata for Java could mean to know all the transitive dependencies and system dependencies (for example, the compression tool for classfiles could be a system dependency)

maybe not too relevant for Java, but it was for C/android

Step 3

  • Compare the artifacts listed in output with the ones on maven central ( <buildspec> does that in reference implementation).
  • mvn package for the first build and mvn package without snapshot lookup for the second build (rebuild).

Step 4

The differences could be

  • order of classfiles in archives
  • absolute and relative paths of resources
  • differences in classfiles
  • difference in manifest files

Reference implementation uses diffoscope

Step 5

A different environment could be Jenkins, CircleCI, a separate GitHub action runner with a different architecture.

In theory, architecture should not matter as jars are supposed to be independent of this.

Step 6

  • Let user’s reproduce the CI based on the build step _ Provide tooling for reproducing it. Example: gorebuild is a tool to reproduce go toolchain.

From here on, it gets abstract

Step 7

Document why the artifacts generated are not reproducible and give reasons why they are not. For example, the signature difference. In Step 6, users could be told to strip signature before comparing.

Step 8,9,10 are release related so we did not discuss them in depth.

Step 8

Project README should tell how to verify build attestation.

Step 9

Have your CI sign the artifacts.

Step 10

Implementing deploy policy is a responsibilty taken by the artifact hosting service (maven central) in Java ecosystem. For example, it checks your manifest (pom.xml) for certain requirements before deploying.

Last takeaway of this session was that the framework was supported by people working in C and android ecosystems. However, commercial code is a hard problem.