Shipping reproducible binaries on github: repro-env

kpcyrd kpcyrd at
Sat Jul 8 21:18:11 UTC 2023


my initial interest in reproducible builds was "how do I distribute 
pre-compiled binaries on github without people raising security concerns 
about them".

I've cycled back to this original problem about 5 years later and built 
a tool that is meant to address this:

It works by adding two more files into your git repository that work 
together like Cargo.toml/Cargo.lock or package.json/package-lock.json:

- **repro-env.toml**: this describes the environment you're aiming for, 
eg. "the latest debian bookworm, with rust and gcc installed, everything 
fully upgraded"
- **repro-env.lock**: this is the resolved state from back then, with a 
list of .deb files, their version and sha256

The repro-env.lock is very similiar to buildinfo files in eg. Arch Linux 
or Debian.

For the operating system base it's using **podman** internally (with 
unprivileged user namespaces) and **repro-env.lock** also tracks a 
container image by its `@sha256:`.

The build directory is always mounted to /build/, most other things are 
provided by the pinned container image, eg the username or any 
environment variables.

Additional packages can be installed from these two archive services:


For example for repro-env itself the **repro-env.toml** looks like this 
(I found this environment works slightly better for static binaries than, which of course can also be used):

image = ""

system = "archlinux"
dependencies = ["make", "musl", "rust-musl"]

The resolved dependency-lock file then may look something like this:

image = 
" at sha256:6568d3f1f278827a4a7d8537f80c2ae36982829a0c6bccff4cec081774025472"

name = "binutils"
version = "2.40-6"
system = "archlinux"
url = 
sha256 = "b65fd16001578e10b602e577a8031cbfffc1164caf47ed9ba00c60d804519430"
signature = 

# [...]

name = "rust"
version = "1:1.69.0-3"
system = "archlinux"
url = 
sha256 = "b8eb31a2eb80efab27bb68beab80436ed3e1d235a217c3e24ba973936c95839e"
signature = 

This is usually sufficient to achieve reproducible builds. This tool, of 
course, does not prevent you from doing something silly that breaks 
reproducible builds, like recording `uname` output, the current time, or 
the order the kernel responds to readdir() syscalls. *wink*

There are 4 example projects here, with Rust, Golang and C twice:

The overall concept works so well, github actions CI always builds all 4 
projects for every commit and verifies the sha256 still matches:

The sha256 of repro-env v0.2.0 for x86_64 Linux is:


It can be downloaded here:

It can be built from this git commit:


Let me know what you think. 🌈


More information about the rb-general mailing list