--- title: Reproducibility in functional package management date: 2025-2-11 date-format: long lightbox: true logo: telecom.png margin-top: "0px" author: - name: given: Julien family: Malka url: https://luj.fr email: julien.malka@telecom-paris.fr orcid: 0009-0008-9845-6300 roles: - conceptualization - investigation - writing – original draft affiliations: - id: telecom name: Télécom Paris, Institut Polytechnique de Paris fig-align: center code-overflow: wrap code-line-numbers: false css: styles.css format: metropolis-beamer-revealjs: theme: slide.scss toc: false toc-title: Plan toc-depth: 2 slide-level: 2 slide-number: true --- ## Research topics **Main topics:** Cybersecurity & Software engineering *How can one trust the software installed on one’s system is not malicious?* - What if we make the assumption that the software is **open source**? ## Software supply chain ::: {.r-fit-text} **Definition:** All the **components**, **tools** and **processes** used to **produce**, **compile** and **distribute** software. - An increasing number of attacks that target the software supply chain of the software instead of the software itself : for example *Solarwinds* (2020). - Will to create security norms of the software supply chain (*USA Executive order on improving the nation’s cybersecurity*/*EU Cyber Resilience Act*). ::: ::: {#fig-eval-build} ![](./software_supply_chain.png){.r-stretch} Software supply chain overview ([slsa.dev](https://slsa.dev)) ::: ## Main PhD research question How to increase trust in the Open Source Software Supply Chain with **functional package managers** and **reproducible builds**? ## Functional package managers {auto-animate="true"} New software deployment model (from which **Nix** has been the first example). ```nix { stdenv, lib, fetchFromGitHub }: ``` ## Functional package managers {auto-animate="true"} New software deployment model (from which **Nix** has been the first example). ```nix { stdenv, lib, fetchFromGitHub }: stdenv.mkDerivation rec { version = "1.3.7"; pname = "htpdate"; src = fetchFromGitHub { owner = "twekkel"; repo = pname; rev = "v${version}"; sha256 = "sha256-X7r95Uc4oGB0eVum5D7pC4tebZIyyz73g6Q/D0cjuFM="; }; ``` ## Functional package managers {auto-animate="true"} New software deployment model (from which **Nix** has been the first example). ```nix { stdenv, lib, fetchFromGitHub }: stdenv.mkDerivation rec { version = "1.3.7"; pname = "htpdate"; src = fetchFromGitHub { owner = "twekkel"; repo = pname; rev = "v${version}"; sha256 = "sha256-X7r95Uc4oGB0eVum5D7pC4tebZIyyz73g6Q/D0cjuFM="; }; makeFlags = [ "prefix=$(out)" ]; ``` ## Functional package managers {auto-animate="true"} ::: {.r-fit-text} New software deployment model (from which **Nix** has been the first example). ```nix { stdenv, lib, fetchFromGitHub }: stdenv.mkDerivation rec { version = "1.3.7"; pname = "htpdate"; src = fetchFromGitHub { owner = "twekkel"; repo = pname; rev = "v${version}"; sha256 = "sha256-X7r95Uc4oGB0eVum5D7pC4tebZIyyz73g6Q/D0cjuFM="; }; makeFlags = [ "prefix=$(out)" ]; meta = with lib; { description = "Utility to fetch time and set the system clock over HTTP"; platforms = platforms.linux; license = licenses.gpl2Plus; maintainers = with maintainers; [ julienmalka ]; }; } ``` ::: ## Evaluation->Build pipeline ::: {#fig-eval-build} ![](./eval-build.png){.r-stretch} Eval-build pipeline ::: ## Functional package managers for SSC security Functional package managers also have interesting properties for software supply chain security (which are of interest for us): - Builds from source; - Sandboxed compilation. ## Functional package managers for SSC security - Installed packages create a static graph structure (a Merkle tree) that can be analysed in order to find known vulnerability in the dependencies. ::: {#fig-eval-build} ![](./graph.png){.r-stretch} Example of a package dependency graph ::: ## Binary distribution - It is not always reasonable to compile all the software a user wants to install on their own machine: creates the necessity of binary caches ; - **But** binary caches make us lose some of the interesting security properties of functional package managers. ## Reproducible builds {.lol} ![](rb.png){height='4em' fig-align="center"} A build is **reproducible** if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts. ## Why is build reproducibility important? ::: {#fig-rb} ![](rb-verif.png){.r-stretch fig-align="center"} Leveraging reproducible-builds to increase trust in distributed artifacts. ::: ## Research questions {auto-animate="true"} **How reproducible is software in the functional package management model?** - Is Nix evaluation reproducible? Can we reproduce *build environments* of Nix packages? - Do functional package management enable **bitwise build reproducibility**? ## Reproducibility of build environments {auto-animate="true"} - Is Nix evaluation reproducible? Can we reproduce *build environments* of Nix packages? :::: {.columns} ::: {.column width="50%"} ![](./icse.jpeg){height='14em'} ::: ::: {.column width="50%"} **"Reproducibility of Build Environments through Space and Time"**, ICSE 2024 (New Ideas and Emerging Results track), *J. Malka, S. Zacchiroli, T. Zimmermann*. ::: :::: ## Reproducibility of build environments We say that two build environments are identical if they contain the **exact same set of executables, up to their specific versions**. ![](./env.png) ## Reproducibility in Space ::: {#fig-rb} ![](./space.png) Reproducibility of build environments in Space ::: ## Reproducibility in Time ::: {#fig-rb} ![](./time.png){.r-stretch} Reproducibility of build environments in Time ::: ## Research questions ::: {.incremental} - **RQ1:** Is space and time reproducibility of build environments achievable with Nix ? - **RQ2:** Does it allow rebuilding of past software versions ? ::: ## Experimental protocol ::: {.incremental} 1) Sample 200 revisions of the Nix software repository, picked from 2017 to 2023; 2) For each sampled revision, perform the **evaluation** of each package and compare with the historical truth (historical CI results); 3) For the *oldest revision* of our samples, perform the **build** of each package and compare with the historical truth. ::: ## Results {auto-animate="true"} **RQ1:** *Reproducibility of build environments* - We were able to **reproduce the build environment of 99.99% of the packages** we tested; - Discrepancies we found were due to the (unfortunate) use of some of Nix’s impure builtins. ## Results {auto-animate="true"} **RQ1:** *Reproducibility of build environments* - We were able to **reproduce the build environment of 99.99% of the packages** we tested; - Discrepancies we found were due to the (unfortunate) use of some of Nix’s impure builtins. **RQ2:** *Rebuilding past software versions* - We were able to **build successfully 14233 out of the 14242 (99.94%) packages that were built successfully by CI in 2017**; - Discrepancies we found were due to leakages of the Nix build sandbox, that we wish to investigate further. ## Research questions {auto-animate="true"} **How reproducible is software in the functional package management model?** - Is Nix evaluation reproducible? Can we reproduce *build environments* of Nix packages? - Do functional package management enable **bitwise build reproducibility**? ## Reproducibility of build environments {auto-animate="true"} - Do functional package management enable **bitwise build reproducibility**? :::: {.columns} ::: {.column width="50%"} ![](./msr.jpeg){height='14em'} ::: ::: {.column width="50%"} **"Does Functional Package Management Enable Reproducible Builds at Scale? Yes."**, MSR 2025, *J. Malka, S. Zacchiroli, T. Zimmermann*. ::: :::: ## Nix **does not** garantee reproducible builds! ```nix let pkgs = import { }; in pkgs.runCommand "random" { } '' echo $RANDOM > $out '' ``` ```{mermaid} flowchart TD A[nix-build] A --run 1--> B[12505] A --run 2--> C[29217] ``` → Will produce an artifact with a different number at each run! ## So how reproducible packages of the Nix distribution are? ::: {#fig-monitoring} ![](monitoring.png) [https://reproducible.nixos.org](https://reproducible.nixos.org) ::: ## So how reproducible packages of the Nix distribution are? ::: {#fig-diffoscope} ![](diffoscope.png) Example of a diffoscope. ::: **Problem:** - Only monitors a small subset of `nixpkgs` (~1300 packages for the Gnome image runtime closure) ## Research questions ::: {.incremental} - **RQ1:** What is the evolution of bitwise reproducible packages in `nixpkgs` between 2017 and 2023? - **RQ2:** What are the unreproducible packages? - **RQ3:** Why are packages unreproducible? - **RQ4:** How are unreproducibilities fixed? ::: ## Research methodology ::: {#fig-methodology} ![](pipelinev2.png){fig-align="center"} Pipeline summarizing our research methodology. ::: ## A few figures ::::{.columns} ::: {.column width="60%"} ::: {#fig-diffoscope} ![](./ecosystems.png) Evolution of the size of the nine most popular software ecosystems in `nixpkgs`. ::: ::: ::: {.column width="40%"} - 709 816 packages built; - 14 296 total build hours; - 548 390 tracked by name and corresponding to 59 103 unique packages associated to a specific software ecossytem . ::: :::: ## RQ1: Evolution of bitwise reproducible packages ::: {#fig-overall} ![](reproducibility-overall-relative.png){.r-stretch fig-align="center"} Proportion of reproducible, rebuildable and non-rebuildable packages over time. ::: ## RQ1: Evolution of bitwise reproducible packages ::: {#fig-overall2} ![](reproducibility-overall-absolute.png){.r-stretch fig-align="center"} Absolute numbers of reproducible, rebuildable and non-rebuildable packages over time. ::: ## RQ1: Evolution of bitwise reproducible packages ::: {#fig-overall2-reg} ![](reproducibility-overall-absolute-reg.png){.r-stretch fig-align="center"} Reproducibility regression around June 2020. ::: ## RQ2: What are the unreproducible packages? ::: {#fig-diff} ![](./reproducibility-ecosystems.png){.r-stretch fig-align="center"} Proportion of reproducible packages belonging to the three most popular ecosystems and the base namespace of nixpkgs. ::: ## RQ3: Why are packages unreproducible? ::: {#fig-diff} ![](evolution-heuristics.png){.r-stretch fig-align="center"} Evolution of the number of packages that are matched by each of our heuristics, over time. ::: ## RQ4: How are unreproducibilities fixed? - Sampled 100 fixes in our dataset of reproducibility fixed (obtained by bisection of the `nixpkgs` repository): → **In 93 instances, "reproducibility" was not mentionned on the pull request / commit message.** → **In 75 cases the fix was merely a package update.**
- Studied the 15 most impactful fixes (from 3052 to 27 packages fixed): → **In 8/15 instances, the reproducibility issue being fixed is documented.** ## Conclusion - Bitwise reproducibility in `nixpkgs` as of 2023: 91%; - This justifies investing resources/conducting research on distributed cache solutions relying on build reproducibility. ## Thank you for your attention!

My socials:

{{< bi mastodon >}} luj@chaos.social {{< bi envelope >}} julien.malka@telecom-paris.fr :::: {.columns} ::: {.column width="50%"} ![](qr-icse.png){height='11em'} ::: ::: {.column width="50%"} ![](qr-msr.png){height='11em'} ::: :::: ## RQ1: Evolution of bitwise reproducible packages ::: {#fig-overall2-reg} ![](./sankey-average.png){fig-align="center"} Sankey graph of the average flow of packages between two revisions, excluding the revision from June 2020, considered as an outlier. :::