home / projects / reprobe

Reprobe

A reproducible-build verifier that rebuilds an artifact from pinned source in independent, hermetic environments and reports exactly where and why the outputs diverge.

Case study

Nix · Go · Reproducible builds

Overview

Designed Reprobe, a verification tool for the claim that matters most in a software supply chain: that the binary you run is the one that was reviewed. It rebuilds the same source in two or more isolated environments, compares the results by content hash, and produces a signed attestation plus a structural diff when they disagree.

Problem

A published checksum only proves a file did not change after it was built. It says nothing about whether the build itself was honest. Reproducibility is the missing check, but in practice builds drift on timestamps, absolute paths, file ordering and toolchain versions, and tracking down the cause by hand is slow enough that most teams never verify.

Constraints

  • Builds must be hermetic: pinned toolchain, no network access during the build step
  • Verification must not trust any single build machine, including the author's
  • Divergence must be explained (which file, which section, which cause), not just detected
  • Output must be machine-readable so it can gate a release pipeline

Approach

Nix flakes pin the entire toolchain and dependency closure, so the build inputs are identical everywhere. A Go orchestrator launches each rebuild in its own sandbox, collects the outputs, normalizes known-benign metadata, and hashes the result. When hashes differ, a structural diff walks archives and ELF sections to point at the first meaningful divergence. Results are written as an attestation record that can be signed and verified later.

Key decisions

Nix as the build substrate

Reasoning: Nix describes a build as a pure function of its inputs, which is the property reproducibility needs. Pinning the full closure removes the largest class of drift before any comparison is attempted.

Alternatives considered:

  • Container images (layer timestamps and unpinned base images reintroduce drift)
  • Distro packaging toolchains (hard to pin and audit at the dependency level)

Attestation records over ad-hoc logs

Reasoning: A structured, signable record of inputs, environment and output hashes can be verified by someone who was not present for the build, and slotted into a release gate without parsing free text.

Alternatives considered:

  • Plain build logs (not verifiable, not machine-readable)
  • A central verification server (reintroduces a single point of trust)

Tech stack

Nix (flakes)GoLinux namespacesELF / archive diffingSigned attestations

Result & impact

Verification model
Independent rebuilds compared by content hash
Build environment
Hermetic, no network at build time
Output
Signed attestation plus human-readable diff report
Status
Prototype in active development

The design target is to turn 'trust the build' into 'check the build': a release either reproduces independently or fails with a specific, explainable reason. Reprobe is a working prototype and feeds the reproducible-builds side of my research.

Learnings

  • Most irreproducibility comes from a short list of causes (timestamps, paths, ordering, locale), so normalizing them early makes the real problems visible.
  • A verifier that cannot explain a mismatch gets ignored; the diff report matters as much as the hash comparison.
  • Hermetic builds are as much a policy problem as a technical one: every allowed escape hatch becomes a place for drift.

Additional context

Reprobe sits directly under my reproducible-builds research area. The same question runs through it as through the rest of my work: what does the system assume, and what happens when that assumption is false?

A rebuild that matches is only meaningful if the environments are genuinely independent, so the orchestrator treats shared state between builders as a defect to be eliminated rather than a convenience.

All projects

Tags

#reproducibility#supply-chain#tooling

Related

shares a tag