NixOS Reproducible Builds: minimal ISO successfully independently rebuilt
NixOS has reached a milestone by independently rebuilding its minimal installation ISO bit-for-bit, prompting broader examination of what “reproducibility” means in practice. Commenters distinguish Nix’s input-level reproducibility (same configuration yields the same environment) from full binary reproducibility, compare NixOS’s current coverage to efforts in Debian, Arch, and Guix, and explore related topics like deterministic toolchains, bootstrapping from tiny trusted binaries, and how this all intersects with security, package signing, and software supply-chain risk. Alongside the technical praise, several voices highlight NixOS’s steep learning curve and contrast it with more conventional tools such as Docker, Ansible, and Fedora Silverblue.
Definitions of Reproducibility
- Distinction emphasized between:
- Input reproducibility: same Nix expression + exact hashed inputs ⇒ same environment and behavior (“perfect cache invalidation”). This is Nix/NixOS’ core guarantee.
- Output reproducibility: bit-for-bit identical binaries from the same sources on different machines. The ISO milestone is about this harder problem.
- Clarification that Nix store hashes are (mostly) input-addressed, not content-addressed by default; experimental content-addressed derivations exist but don’t replace reproducible builds.
Current State of NixOS vs Other Distros
- Minimal NixOS ISO is now independently rebuilt bit-for-bit; GNOME ISO may be next.
- Only a small subset of the ~80k nixpkgs packages is systematically tested; regressions have happened (e.g., Python optimization).
- Other projects (Debian, Arch, Guix) systematically test more of their repos and currently report higher coverage; exact comparison is called “unclear” because ecosystems and package counts differ.
- Newer Nix infrastructure (
reproducible.nixos.org) supersedes older r13y.com.
Usability and Learning Curve
- Some users expect “easy reusable configs” and are frustrated (e.g., Hyprland on Nix vs quick Arch setup).
- Advice diverges on whether to start with flakes: some say they’re experimental and confusing, others say they dramatically improve the UX and consistency.
- Starter config repos and home-manager are recommended to ease entry.
Technical Sources of Non-Determinism
- Common causes: timestamps, build-time “version strings,” nondeterministic hashmap iteration, pointer-based ordering, parallelism and race-sensitive algorithms, randomized runtimes.
- Reproducible-builds community patterns like
SOURCE_DATE_EPOCHare used (e.g., Python build date derived from source archive timestamps). - Filesystem/image creation ordering (e.g., ISO extents) required specific tooling and invocation tweaks.
Bootstrapping and “Trusting Trust”
- Guix highlighted for a parallel milestone: bootstrapping a full toolchain from a 357-byte seed, via a multi-stage hex/assembler chain.
- This and Nix’s ISO work are seen as complementary steps toward end-to-end verifiable systems.
- Reproducible builds help with “trusting trust” but don’t fully solve it; diverse double-compiling and full-environment bootstrapping are mentioned as deeper approaches.
Security, Package Signing, and Supply Chain
- Strong disagreement over Nix’s lack of maintainer-level package signing:
- One side: Nix focuses on reproducible, sandboxed builds; users can rebuild and verify outputs, so maintainer signatures add limited value.
- Other side: without signed expressions/commits and a web of trust, supply-chain attacks via compromised developer accounts or infrastructure remain too easy; other distros’ signing practices are cited as better.
- Nix’s binary cache outputs are signed by central keys, but there is no standardized mechanism to require or verify developer/maintainer signatures on package definitions.
- Some argue this is a deliberate design choice to keep Nix composable and decentralized; critics suggest a curated, security-focused layer or fork on top.
Comparisons to Other Systems
- Docker: Nix can build OCI images as pure functions of inputs, avoiding Dockerfile mutability and network fetches.
- Fedora Silverblue / ostree and Ansible: contrasted with NixOS’ fully declarative, immutable, but non-reboot-requiring model.
- OpenBSD: illustrates that post-install randomization (e.g., ASLR, randomized linking) can coexist with reproducible packages, since randomness can be applied after verified artifacts are installed.