Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Shortened JVM build tools section, referring to reproducible-builds.org

...

See below for any ecosystem-specific notes that could be helpful for other projects to make their builds reproducible. If you have additional input to share, feel free to edit this wiki page. If you have questions or want to discuss approaches, you can use the security-discuss mailinglist or Slack channel.

Archive/artifact contents

Including information about the system or environment running the build as well as current-date/time information in Jars breaks reproducibility (1) (2). This includes attributes like:

  • Current/build user
  • Current/build timestamp
  • Hostnames and IP addresses
  • Absolute file system paths
  • Full build tool versions (like Java's java.version or java.vm.version system properties)
  • CI build number
  • ...

Java / Maven

If you have a project that is built with Apache Maven, refer to the Configuring for Reproducible Builds guide.

Java / Gradle, Maven and sbt

Refer to the JVM build tools documentation on reproducible-builds.org.

Python

Modern Python tooling (such as Flit and Hatch) support reproducible builds for pure-Python projects. You can read more about reproducible build support in Flit reproducible build docs and Hatch reproducible build docs. It's a bit more complex if your assets require native compilation, but if you can assure that your native compilation produces reproducible libraries on its own the packaging tool will produce reproducible builds..

...

You can read more about reproducible build support in Flit reproducible build docs and Hatch reproducible build docs.

Helm package

The helm package command from Helm versions before 4.0.0 cannot produce reproducible archives.

Since Helm version 4.0.0, it is possible to produce reproducible archives, even with the --sign option. The package archive entries get a constant uid/gid and fixed POSIX permissions. The file modification time is set to the source files' modification time.
Consider setting a constant file modification time, for example using find $PACKAGE_CONTENTS_DIRECTORY -exec touch -d "2000-01-01 00:00:00" {} +

Preparing reproducible .tar.gz packages

If you prepare source-tarball, or another .tar.gz package you can have script use scripts similar to to this one - which takes the same source_date_epoch and repacks the .tar.gz file to be reproducible. There are however few gotchas:

1) Make sure to remove permissions for "group" and "other" for all files that you add to the repository. This is needed because group/other permissions have different default settings (based on umask) and clearing them is the most certain way of reproducibility. This can be done in a few ways:

  • if you use git archive  - "-c tar.umask=0077" removes all permissions for group/others
  • Just run chmod -R og= <directory>  for the directory to compress - before running the reproducible script

2) if you use git archive , you can exclude some of the directories with .gitattributes  eport-ignore  specification

3) Consider using a fixed mtime and not using git-archive's gzip. For example:  git archive --mtime="1980-02-01 00:00:00 UTC" --format=tar HEAD | gzip -6 --no-name > my-archive.tar.gz

4) Gzip can also contain non-reproducible information. Consider using the strip-nondeterminism tool, which is available for many systems. When using the gzip tool alone, consider adding the --no-name with a fixed compression level, for example gzip --no-name -6.

5) ZIP files are not reproducible by default and the zip tool does not offer an easy way to generate reproducible zip archives. Consider using the strip-nondeterminism tool, which is available for many distributions/package managers (Ubuntu, Debian, brew and more).