CI/CD
GitHub Actions -välimuisti: miten se toimii ja mitä se piilottaa
GitHub Actionsin välimuisti tallentaa tiedostoja työnkulun ajojen välillä, joten jobit ohittavat lataukset, jotka ne ovat jo tehneet. Se nopeuttaa buildeja. Se tarkoittaa myös, että paketit päätyvät buildiisi ilman hakua, eikä useimmissa buildin tallenteissa tätä näy lainkaan.
Päivitetty
Miten välimuisti toimii
actions/cache-action tallentaa joukon polkuja avaimen alle jobin lopussa ja palauttaa ne myöhemmän jobin
alussa. Tyypillinen npm-asetus tallentaa paketinhallinnan latausvälimuistin ja muodostaa avaimen lukitustiedostosta:
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
- run: npm ci
Palautettaessa action etsii ensin täsmällistä vastinetta avaimelle key, sitten osittaista vastinetta ja
sitten vuorollaan jokaista restore-keys-etuliitettä. Kun etuliitteeseen täsmää useampi välimuisti, se
palauttaa viimeksi luodun. Tämä varavaihtoehto pitää buildit nopeina lukitustiedoston muuttuessa, ja se tarkoittaa
myös, että jobi voi lähteä liikkeelle välimuistista, joka on luotu vanhemmalle lukitustiedostolle.
Usein actionia ei tarvita lainkaan. setup-node, setup-python, setup-java,
setup-go, setup-ruby ja setup-dotnet sisältävät välimuistituen. Node.js:ssä
setup-node tallentaa npm:n, Yarnin ja pnpm:n globaalit pakettitiedot, ei node_modules-hakemistoa,
ja ottaa npm-välimuistin käyttöön automaattisesti, kun package.json ilmoittaa npm:n
packageManager-kentässään.
Laajuus ja rajat
| Sääntö | Mitä GitHub tekee |
|---|---|
| Mitä välimuisteja ajo voi palauttaa | Oman haaransa ja oletushaaran; pull requestit myös kohdehaaransa |
| Mitä pull request voi kirjoittaa | Vain välimuisteja, jotka on rajattu sen merge-refiin, ei oletushaaraan |
| Tallennustila | Oletuksena 10 Gt repositoriota kohden; organisaation ja enterprisen omistajat voivat nostaa sitä |
| Poistaminen | Merkinnät, joita ei ole käytetty yli 7 päivään, sekä vähiten käytetyt, kun tila on täynnä |
| Salaisuudet | Älä tallenna niitä välimuistiin: kuka tahansa, jolla on pull request -oikeudet, voi lukea välimuistin sisällön |
Mitä välimuisti piilottaa SBOM:ltasi
Välimuisti on oikotie pakettirekisterin ohi. Se on sen tarkoitus, ja juuri siksi se myös sekoittaa jokaisen tallenteen siitä, mitä buildi käytti:
- Ei latausta, ei jälkeä. Välimuistista palautetut paketit asennetaan ilman pyyntöä rekisteriin. Buildin verkkoliikenteestä koottu tallenne ohittaa ne, ellei se seuraa välimuistia.
-
Vanha sisältö uuden avaimen alla. Osittainen
restore-keys-vastine palauttaa välimuistin, joka on luotu aiemmalle lukitustiedostolle. Asennus lisää tai korvaa muuttuneet osat, mutta se, mistä jobi lähti liikkeelle, ei ole sitä, mitä nykyinen lukitustiedosto kuvaa. - Muutakin kuin riippuvuutesi. Välimuisteissa on myös build-työkaluja, kääntäjiä ja generoituja tiedostoja, joita mikään sovelluksen manifesti ei luettele.
- Skannaus ei voi tietää. Lukitustiedostoon perustuva SBOM kuvaa sen, mitä lukitustiedostossa lukee, asensiko jobi välimuististaan juuri sen tai ei.
Miten tämä liittyy laajempaan ongelmaan, kerrotaan sivuilla miksi lukitustiedosto ei ole tallenne toimitetusta ja transitiiviset riippuvuudet.
Välimuistin myrkyttäminen
Välimuistit jaetaan repositorion työnkulkujen kesken, mikä tekee niistä reitin työnkulusta toiseen. Toukokuussa 2024
tietoturvatutkija Adnan Khan osoitti, että kuka tahansa, joka pystyy suorittamaan koodia oletushaaran kontekstissa
haavoittuvan pull_request_target-työnkulun tai kaapatun riippuvuuden kautta, voi ylikirjoittaa
tiedostoja työnkuluissa, jotka palauttavat välimuisteja. Käynnissä olevan jobin välimuistitokenilla hyökkääjä voi
täyttää repositorion välimuistin niin, että GitHub poistaa aidot merkinnät, ja kirjoittaa sitten myrkytettyjä
merkintöjä samoilla avaimilla. Julkaisutyönkulku, joka palauttaa ne, ajaa hyökkääjän tiedostot omilla
salaisuuksillaan.
Riskin pienentämiseksi:
- Buildaa julkaisut puhtaasta tilasta tai välimuisteista, joihin vain julkaisutyönkulku kirjoittaa.
- Älä koskaan aja epäluotettavaa pull request -koodia oletushaaran kontekstissa.
- Pidä salaisuudet ja tokenit poissa välimuistiin tallennetuista poluista.
- Käsittele välimuistin palauttamaa sisältöä buildin syötteenä, joka vaatii saman tarkastelun kuin lataus.
Miten CRACI käsittelee välimuisteja
CRACI on GitHub Actions -runneri, joten actions/cache ja setup-*-välimuistit toimivat kuten
nyt, konttikerrosten välimuistin rinnalla. Välimuisti on myös osasyy siihen, että CRACI ajaa buildit noin kaksi kertaa
GitHubin ylläpitämiä runnereita nopeammin, nopeamman laitteiston ja lyhyempien jonotusaikojen lisäksi.
Tallenne on se, mikä muuttuu. CRACI:n paketit tunnistava välityspalvelin (proxy) tallentaa paketit, jotka jobi hakee, ja näyttö kulkee välimuistien mukana: kun jobi palauttaa välimuistin, CRACI siirtää tuntemansa riippuvuudet kyseisen jobin SBOM:iin.
- Kattavuus välimuistikohtaisesti. Jokaisella välimuistilla on kattavuustila, kuten jokaisella jobilla. Jobi, joka palauttaa epätäydellisen välimuistin, saa epätäydellisen SBOM:n, ja sen tuottama välimuisti kuljettaa tilan eteenpäin, joten aukko ei koskaan muutu huomaamatta kattavaksi tallenteeksi.
- Ei arvailua arkistosta. CRACI ei lue välimuistiarkiston sisällä olevia pakettimanifesteja. Se tietää, mitä välimuistissa on, koska se tallensi jobin, joka loi sen.
-
Yksi välimuisti tuottavaa jobia kohden pitää näytön luotettavana, yhdessä tuottavan jobin
egress-käytännön kanssa, joka on asetettu muotoon
default: deny. Välimuistin ja SBOM:n kattavuuden opas kertoo yksityiskohdat.
Lue tallennuksen toiminnasta sivulta buildin aikana tallennetut SBOM:t tai varaa demo ja aja yksi välimuistia käyttävistä työnkuluistasi CRACI:lla.
GitHub Actions -välimuisti: usein kysytyt kysymykset
Kuinka kauan GitHub säilyttää Actions-välimuistia?
GitHub poistaa välimuistimerkinnät, joita ei ole käytetty yli 7 päivään. Kun repositorio ylittää tallennusrajansa, oletuksena 10 Gt, se poistaa välimuisteja myös viimeisimmän käytön mukaan, vanhimmasta alkaen.
Tallentaako setup-node node_modules-hakemiston välimuistiin?
Ei. actions/setup-noden cache-syöte tallentaa paketinhallinnan globaalit pakettitiedot npm:lle, Yarnille tai pnpm:lle, ei node_modules-hakemistoa. Asennusvaihe ajetaan silti, mutta se lukee paketit palautetusta välimuistista lataamisen sijaan.
Voiko pull request lukea päähaaran välimuisteja?
Kyllä. Työnkulun ajo voi palauttaa välimuisteja omasta haarastaan ja oletushaarasta, ja pull request voi palauttaa välimuisteja myös kohdehaarastaan. Pull requestissa luodut välimuistit rajataan sen merge-refiin, joten niitä ei voi kirjoittaa oletushaaran alueelle.
Onko Actions-välimuistin käyttö turvallista julkaisutyönkuluissa?
Se on kompromissi. Vuonna 2024 julkaistu tutkimus osoitti, että kuka tahansa, joka pystyy ajamaan koodia oletushaaran työnkulussa, voi myrkyttää välimuisteja, joita muut työnkulut palauttavat, myös julkaisutyönkulut. Työnkulut, jotka julkaisevat versioita tai hallussaan pitävät käyttöönoton salaisuuksia, ovat turvallisempia, kun ne buildaavat puhtaasta tilasta tai välimuisteista, joihin vain ne itse kirjoittavat.
Muuttaako palautettu välimuisti SBOM:iani?
Voi muuttaa. Välimuistista palautetut paketit asennetaan lataamatta, joten verkkoliikenteestä koottu tallenne ohittaa ne, ellei se seuraa välimuistia. Eikä lukitustiedoston skannaus kerro, sisälsikö välimuisti täsmälleen nuo versiot.
Pidä välimuistisi ja kattava SBOM
Aja työnkulkusi CRACI:lla: välimuistit nopeuttavat buildia edelleen, ja niiden kuljettamat riippuvuudet pysyvät jokaisen jobin tallennetussa SBOM:ssa.
Varaa demo