Tuan-Anh Tran
January 21, 2024

Reproducibility

Posted on January 21, 2024  •  2 minutes  • 369 words

What is reproducibility?

Reproducible builds are a set of software development practices that create an independently-verifiable path from source to binary code.

as defined by reproducible-builds.org

Why does it matter?

The motivation behind the Reproducible Builds project is therefore to allow verification that no vulnerabilities or backdoors have been introduced during this compilation process

So assume reproducibility can be achieved and attested, and if we trust the published source, this artifact can be trusted too.

There are 2 concepts here:

This is very crucial in the software supply chain security.

How to produce a reproducible container image

Let’s take an go:1.21-bookwarm image for example. Source for Dockerfile is available here .

FROM buildpack-deps:bookworm-scm

# install cgo-related dependencies
RUN set -eux; \
	apt-get update; \
	apt-get install -y --no-install-recommends \
		g++ \
		gcc \
		libc6-dev \
		make \
		pkg-config \
	; \
	rm -rf /var/lib/apt/lists/*

Let’s try to make this image reproducible.

By default, the official debian image use ftp.debian.org. Packages in this repository get updated and old packages get dumped all the time. So reproducibility is pretty much gone.

Thanksfully, there’s http://snapshot.debian.org which provides access to old packages based on dates & version numbers. You can also use http://snapshot-cloudflare.debian.org/archive/ as alternative.

So how do we get reproducible build with this? By locking down the snapshot of the repository as the build time.

By default, the content of default repo at /etc/apt/sources.list.d/debian.sources looks like this

Types: deb
# http://snapshot.debian.org/archive/debian/20240110T000000Z
URIs: http://deb.debian.org/debian
Suites: bookworm bookworm-updates
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
# http://snapshot.debian.org/archive/debian-security/20240110T000000Z
URIs: http://deb.debian.org/debian-security
Suites: bookworm-security
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Notice the commented line http://snapshot.debian.org/archive/debian-security/20240110T000000Z. This is the snapshot URL. If we use this URL, we can lock down the version of all the packages we want to install.

But how do we get that URL? It’s simple.

SOURCE_DATE_EPOCH=$(stat --format=%Y /etc/apt/sources.list.d/debian.sources)
# => 1704844800
printf "%(%Y%m%dT%H%M%SZ)T\n" "$SOURCE_DATE_EPOCH"
# => 20240110T000000Z
# => http://snapshot.debian.org/archive/debian-security/20240110T000000Z

Now if you run apt update, you will get the sth like this instead

apt update
Get:1 http://snapshot-cloudflare.debian.org/archive/debian/20240110T000000Z bookworm InRelease [151 kB]
Get:2 http://snapshot-cloudflare.debian.org/archive/debian-security/20240110T000000Z bookworm-security InRelease [48.0 kB]

And now, you can reliably reproduce this image because the rest of the go’s Dockerfile is already reproducible (downloading go with shasum check).

Follow me

Here's where I hang out in social media