Toistettava buildi
Toistettava buildi tuottaa bitilleen identtisen tuloksen aina, kun kuka tahansa buildaa saman lähdekoodin samassa build-ympäristössä samoilla build-ohjeilla.
Päivitetty viimeksi: 11. marraskuuta 2026
Toistettava buildi (reproducible build) tuottaa bitilleen identtisen tuloksen aina, kun kuka tahansa buildaa saman lähdekoodin samassa build-ympäristössä ja samoilla build-ohjeilla. Tämä on Reproducible Builds -projektin määritelmä. Tuloksella tarkoitetaan tässä artefakteja, joita varten buildi tehdään: suoritettavia tiedostoja, jakelupaketteja, kontti- tai tiedostojärjestelmäkuvia. Lokit eivät lasketa. "Se buildautuu taas" ei ole sama asia; toistettava tarkoittaa, että tavut täsmäävät.
Miksi useimmat buildit eivät ole toistettavia
- Riippuvuuksien selvittäminen buildin aikana. Ilman lukitustiedostoa (lockfile) paketinhallinta valitsee versiot buildin ajohetkellä. PyPI-riippuvuuksien selvitys voi päätyä eri tulokseen sen mukaan, missä järjestyksessä vastaukset saapuvat, versioväli siirtyy uuden julkaisun ilmestyessä, ja muuttuva tagi, kuten
latest, osoittaa uuteen paikkaan. - Ympäristö. Aikaleimat, tiedostopolut, kieliasetukset (locale) ja isäntäkoneen omat työkalut päätyvät artefakteihin.
- Satunnaisuus. Build-vaiheet voivat luoda tunnisteita, järjestää tiedostoja tiivisteen mukaan tai ajaa työtä rinnakkain eri järjestyksessä joka kerta.
Saman commitin buildaaminen kahdesti peräkkäin ei siis takaa samaa tulosta eikä samaa SBOM:ia. Buildi, joka lataa koodia, jota sen lukitustiedosto ei luettele, eli piilotettu riippuvuus, pahentaa tilannetta.
Miten tiimit tekevät buildeista toistettavia
- Kiinnitä ja lukitse jokainen syöte, myös pohjakuvat tiivisteen (digest) ja työkalut version mukaan (katso lukitustiedosto).
- Käytä kellon sijaan kiinteää aikaa:
SOURCE_DATE_EPOCHon vakiintunut ympäristömuuttuja, joka sisältää Unix-aikaleiman, jota build-työkalut käyttävät nykyhetken sijaan. - Poista tai normalisoi build-polut, järjestä tiedostoluettelot ja kiinnitä kieliasetukset.
- Buildaa hermeettisessä ympäristössä, jonka työkaluketju on itsessään kiinnitetty. Nix on yksi tapa tehdä tämä.
- Todenna se: buildaa sama commit kahdesti toisistaan riippumatta (toisella koneella, toisessa polussa, toisena päivänä) ja vertaa tuloksia. Kun tiivisteet eroavat, diffoscope näyttää tarkalleen, mikä muuttui.
Yocto Project osoittaa, miksi toistettavuus on ominaisuus, joka on todennettava eikä oletettava. Sen dokumentaation mukaan projektin buildit ovat olleet toistettavia "binääritasolle asti aikaleimat mukaan lukien" julkaisusta 3.1 lähtien, vain BitBake ja OpenEmbedded-Core takaavat täydellisen toistettavuuden, ja "heti kun lisäät toisen kerroksen, tämä takuu raukeaa". Projekti testaa sen oe-selftest-työkalulla.
Toistettavat buildit ja SBOM:t
Jos jokainen buildi olisi toistettava, voisit buildata vanhan julkaisun myöhemmin uudelleen ja generoida sen SBOM:n. Useimmat eivät ole, joten uudelleenbuildi tai lähdekoodin skannaus tänään kuvaa samankaltaista buildia eikä sitä, jonka toimitit. Tuotannon sisällön näyttävä SBOM on se, joka tallennettiin julkaisun tuottaneesta CI-buildista.
Edes toistettava buildi ei poista tämän tallenteen tarvetta. Täsmäävät tiivisteet todistavat, että kaksi buildia tuotti saman tuloksen; ne eivät luettele, mitä siihen meni. Tarvitset silti inventaarion ja rehellisen ilmoituksen sen SBOM-kattavuudesta. Miksi CI on oikea paikka toimitusketjun tietoturvalle ja SBOM:n parhaat käytännöt esittävät perustelun laajemmin.
SLSA pitää toistettavuutta yhtenä tapana todentaa, että buildi teki sen, mitä se väittää.
Toistettavuuden tiimit saavuttavat build-järjestelmässään työkaluilla, kuten Nixillä, Yoctolla tai Debianin työkaluilla. CRACI ei tee buildeista toistettavia: se tallentaa kunkin buildin SBOM:n buildin aikana, joten tieto siitä, mitä toimitettiin, ei riipu uudelleenbuildaamisesta. Katso buildin aikaiset SBOM:t.