Studien / S18
Was unveränderliche Releases in GitHub-Actions-Workflows schützen
Was schützen die unveränderlichen Releases von GitHub in den Actions-Workflows beliebter Repositories?
Zusammenfassung
Seit dem 2025-10-28 kann ein GitHub-Release als unveränderlich (immutable) veröffentlicht werden: Sein Git-Tag kann dann nicht mehr verschoben oder gelöscht werden. Die Dokumentation von GitHub sagt Autoren von Actions außerdem, dass ein Tag, das sie weiter aktualisieren wollen, etwa das Major-Versions-Tag v1, nicht an ein Release gebunden sein darf, und schlägt vor: „recommend that your users specify a major version“ (empfehlen Sie Ihren Nutzern, eine Major-Version anzugeben). Ein Workflow, der uses: owner/action@v1 schreibt, folgt dieser dokumentierten, vorgesehenen Verwendung, und unveränderliche Releases schützen ihn nicht. Wir haben am 2026-10-03 ausschließlich über die GitHub-API gemessen, was der Mechanismus in der Praxis schützt:
- A: die 1.000 Repositories mit den meisten Sternen unter den öffentlichen Repositories, die kein Fork und nicht archiviert sind und in den letzten 90 Tagen einen Push erhalten haben (Schwelle 29.565 Sterne);
- B: 500 Repositories, zufällig gezogen (Seed 20261003) aus den 20.553 solchen Repositories mit 1.000–5.000 Sternen.
Ihre Workflows im Standard-Branch enthalten 58.690 entfernte uses:-Referenzen in A und 10.472 in B. Jede wurde danach eingeordnet, ob sie per Commit-SHA, per Tag eines unveränderlichen Releases, per veränderlichem Tag oder per Branch gepinnt ist.
Wo der Autor bereits unveränderliche Releases veröffentlicht, ist fast keine Referenz geschützt. Von den Tag-Referenzen auf Actions, deren neuestes Release unveränderlich ist, zeigen in A 312 von 6.898 (4,5 %; 95-%-Konfidenzintervall 2,8–7,1 %, Bootstrap über Repositories) auf ein geschütztes Tag (protected tag), in B 76 von 1.564 (4,9 %). Die geschützten sind konzentriert: Ein einziges Repository enthält 68 der 312, und lässt man ein beliebiges einzelnes Repository weg, ergeben sich 3,6–4,6 %. Fast alle übrigen sind Major-Tags wie @v7. Bei 3.238 von 6.586 (49,2 %) der ungeschützten Referenzen in A (Konfidenzintervall 43,2–56,0 %) zeigt bereits ein Tag eines unveränderlichen Releases auf denselben Commit; ein Wechsel darauf würde also den ausgeführten Code nicht ändern.
Meistgenutzte Actions. 28 der 50 Action-Repositories (56,0 %), die von den meisten Repositories in A genutzt werden, veröffentlichen ihr neuestes Release als unveränderlich. Von GitHub selbst: 12 von 28 (42,9 %) bei actions/* (ja: setup-node, setup-python, setup-go, setup-java; nein: checkout, cache, upload-artifact, download-artifact, github-script) und 3 von 6 (50,0 %) bei github/*.
Den Schutz leistet das SHA-Pinning, und zwar in einer Minderheit der Repositories. Insgesamt sind in A 32.978 von 58.690 entfernten Referenzen (56,2 %; Konfidenzintervall 50,7–61,7 %) per SHA gepinnt, in B 4.812 von 10.472 (46,0 %; Konfidenzintervall 29,0–60,1 %; 37,7 % ohne sein größtes Repository, open-telemetry/opentelemetry-python, das 1.392 Referenzen enthält). Das typische Repository pinnt wenige: Der Median des SHA-Anteils pro Repository liegt in A bei 5,0 % und in B bei 0,0 %. Alle in den Workflow-Dateien geschriebenen entfernten Referenzen sind in A in höchstens 263 von 891 Repositories (29,5 %) per SHA gepinnt, und in 174 von 891 (19,5 %), wenn die 89 nicht mitgezählt werden, die zusätzlich lokale Actions aufrufen, die wir nicht gelesen haben; in B in höchstens 65 von 398 (16,3 %) bzw. 55 von 398 (13,8 %). Unveränderliche Tags: 0,6 % der Referenzen in A, 0,8 % in B.
Das Festschreiben von Abhängigkeiten auf Workflow-Ebene (workflow-level dependency locking), am 2026-03-26 mit „Public preview 3-6 months“ (öffentliche Vorschau in 3–6 Monaten) angekündigt, war am 2026-10-03 noch nicht ausgeliefert: Die zugehörigen Roadmap-Einträge sind offen, und weder ein Changelog-Eintrag noch die Referenz zur Workflow-Syntax dokumentiert es. Diese Zahlen beschreiben den Stand, bevor es ausgeliefert wird.
Frühere Arbeiten. datosh/pinned-actions verfolgt das SHA-Pinning in den 10.000 Repositories mit den meisten Sternen („only 7%“, also nur 7 %, pinnen vollständig, April 2026; 506 von 6.290 Repositories, die Actions nutzen, 8,0 %, in seinem Archiv) und hat im April 2026 eine Prüfung ergänzt, ob das neueste Release unveränderlich ist; joshjohanning/ensure-immutable-actions (seit 2025-11) prüft, ob die Referenzen in Workflows unveränderliche Releases verwenden. Wissenschaftliche Arbeiten maßen 2022 SHA-Pinning bei 1–2 % der Referenzen; eine Arbeit auf der NDSS 2026 ermittelte, dass 16,2 % der Repositories jede Action von Dritten per SHA oder per Tag eines verifizierten Erstellers referenzieren. Unsere 29,5 % weichen von den 8,0 % von datosh vor allem wegen der Grundgesamtheit (Top 1.000 mit jüngster Aktivität, nicht Top 10.000) und des Datums ab; die ersten 1.000 Einträge von datosh selbst ergeben 100 von 781 (12,8 %). Soweit wir feststellen konnten, waren H1 (wie viele Tag-Referenzen unveränderliche Releases schützen) und die 49,2 % mit einem unveränderlichen Tag am selben Commit bisher nicht gemessen worden. Paper und Quellen: https://easybyte.es/lab/studies/s18/paper/.
Automatisierung und Prüfung. KI-Agenten haben die Studie durchgeführt und den Text geschrieben. Ein unabhängiger KI-Prüfer hat die Arbeit geprüft; seine Befunde wurden übernommen (METHOD.md, Abschnitt Deviations).
Interessenkonflikte. EasyByte entwickelt attest-lint und könnte scripts/uses_check.py, den hier verwendeten Klassifikator, als kostenloses Werkzeug veröffentlichen. Anders als ensure-immutable-actions, das SHA-Pins vorschlägt, gibt es für jedes verschiebbare Tag das Tag eines unveränderlichen Releases an, das auf denselben Commit zeigt.
Diese Studie zitieren
EasyxLab (2026). What immutable releases protect in GitHub Actions workflows. Study S18. EasyByte Hub S. Coop. Mad. https://github.com/easybytehub/easyxlab/tree/main/studies/s18-actions-immutable-releases@techreport{easyxlab_s18,
title = {What immutable releases protect in GitHub Actions workflows},
author = {{EasyxLab}},
institution = {EasyByte Hub S. Coop. Mad.},
number = {S18},
year = {2026},
url = {https://github.com/easybytehub/easyxlab/tree/main/studies/s18-actions-immutable-releases}
}