GitHub Actions cache-mode konfigurieren? 2026: Leitfaden zum Schutz vor Cache-Poisoning in der Unternehmens-Mac-CI

GitHub Actions cache-mode konfigurieren? 2026: Leitfaden zum Schutz vor Cache-Poisoning in der Unternehmens-Mac-CI

Befund: Ein Cache-Schreibrecht für nicht vertrauenswürdige Pull Requests kann Inhalte in spätere Builds tragen; der Modus allein isoliert jedoch keinen Mac Runner.

Schnellste Abhilfe: Setzen Sie für nicht vertrauenswürdige Aufgaben read oder none und lassen Sie nur ein getrenntes, vertrauenswürdiges Workflow Cache-Inhalte schreiben. Verwenden Sie write oder write-only erst, wenn der Code und der Schreibpfad dafür freigegeben sind.

Dieser Leitfaden richtet sich an IT- und Plattformverantwortliche, die Berechtigungen und Freigabegrenzen für GitHub Actions festlegen.
Verantwortliche für iOS- und macOS-CI können damit die Risiken zwischen Cache und echtem Mac-Build prüfen.
Sicherheitsverantwortliche erhalten Kontrollpunkte für nicht vertrauenswürdigen Code, Runner und Signaturgeheimnisse.

Zuletzt geprüft am 24.09.2026 anhand der GitHub-Ankündigung zu cache-mode, der Workflow-Syntax, der Cache-Sicherheitsdokumentation und der Sicherheitsdokumentation zu selbst gehosteten Runnern. Prüfen Sie vor einer Änderung erneut, welche Syntax und welcher Standardwert zum Veröffentlichungszeitpunkt gelten.

Die Berechtigungen read, write, write-only und none im Vergleich

read erlaubt das Wiederherstellen eines passenden Caches, aber nicht dessen Speichern. write erlaubt Wiederherstellung und Speicherung. write-only erlaubt das Speichern, nicht aber die Wiederherstellung. none sperrt beide Cache-Aktionen. Laut aktueller Dokumentation ist ohne abweichende Einstellung read-write der Ausgangszustand; legen Sie für kritische Workflows den gewünschten Modus deshalb explizit fest und prüfen Sie die tatsächlich wirksame Einstellung. Die Modi und ihre Steuerung beschreibt die GitHub-Ankündigung zu cache-mode.

Modus Cache wiederherstellen Cache speichern Typischer Einsatz Freigabeeinschätzung
read Ja Nein Nicht vertrauenswürdige Builds, sofern ein Cache aus einer zulässigen Quelle benötigt wird Bedingt freigeben
write Ja Ja Vertrauenswürdige Builds, die einen vorhandenen Cache nutzen und aktualisieren müssen Nur mit geprüftem Schreibpfad
write-only Nein Ja Getrennter Prozess, der Cache-Inhalte bereitstellt, ohne vorherige Inhalte zu konsumieren Nur mit geprüftem Inhalt
none Nein Nein Unbekannter Code, besonders schützenswerte Jobs oder Aufgaben ohne Cache-Bedarf Standard für hohe Unsicherheit

Die Tabelle beschreibt die Cache-Berechtigung, nicht den gesamten Schutzmechanismus. Zusätzlich gelten GitHubs Regeln für Cache-Scope und Auslöser. Eine Berechtigung kann weder eine branchübergreifende Sichtbarkeit herstellen, die der Plattform-Scope nicht zulässt, noch aus einem unsicheren Workflow einen sicheren machen. Die offizielle Referenz zum Dependency-Caching erläutert, wie Cache-Schlüssel und zugelassene Scopes beim Wiederherstellen zusammenspielen.

Standardwert nicht stillschweigend übernehmen

Ein impliziter Standardwert ist ein schlechter Ersatz für eine Sicherheitsentscheidung: Ein später geänderter Workflow kann plötzlich mehr dürfen als beabsichtigt. Prüfen Sie in der Workflow-Syntax, an welcher Stelle cache-mode gesetzt wird, welche Ebene die Einstellung überschreiben darf und ob die Einstellung tatsächlich für den betreffenden Job greift. Dokumentieren Sie den effektiven Wert im Review, nicht nur den Wert, den Sie in einer Vorlage vermuten.

Bewerten Sie die Modi nach dem notwendigen Verhalten, nicht danach, welcher Build gerade am schnellsten wirkt. Ein Job, der ausschließlich Abhängigkeiten lesen muss, braucht kein Schreibrecht. Ein Job, der einen Cache neu erzeugt, sollte nicht zusätzlich ungeprüfte Inhalte aus einer fremden Vertrauensgrenze wiederherstellen. Wenn Sie nicht erklären können, wer den Cache erstellt und wer ihn später konsumiert, setzen Sie zunächst none und klären Sie den Datenfluss.

Cache-Rechte für pull_request nach Vertrauensstufe

Für einen pull_request aus einem Fork ist read nur dann vertretbar, wenn der Workflow einen Cache tatsächlich benötigt und die wiederhergestellten Inhalte als nicht vertrauenswürdig behandelt. Andernfalls ist none die klarere Wahl. Gewähren Sie dem PR-Workflow nicht allein deshalb Schreibrechte, weil ein späterer Build von den gespeicherten Abhängigkeiten profitieren könnte. Für die Verarbeitung von Änderungen aus nicht vertrauenswürdigen Beiträgen ist die passende Grenze der Auslöser und nicht nur der Cache-Modus.

GitHub begrenzt den Zugriff von Pull-Request-Workflows durch Cache-Scopes: Ein solcher Workflow kann in den dokumentierten Fällen Caches aus dem Basisbranch wiederherstellen, darf aber nicht in den Cache-Scope des Basisbranches schreiben. Er kann dennoch einen eigenen, enger begrenzten Cache erzeugen. Das ist keine Garantie, dass wiederhergestellte Inhalte sauber oder ungefährlich sind. Lesen Sie dazu die Dokumentation zu Cache-Sicherheit und Scopes.

Ein pull_request sollte deshalb getrennt nach Datenzugriff, Cache-Wiederherstellung und Seiteneffekten bewertet werden. Für Build-Tests ohne Cache-Bedarf ist none einfach zu begründen. Muss der Job Abhängigkeiten wiederherstellen, begrenzen Sie den Zugriff auf read, prüfen Sie Schlüssel und Wiederherstellungspräfixe und verhindern Sie, dass ein nicht vertrauenswürdiger Lauf einen Cache erzeugt, den ein privilegierter Job später als vertrauenswürdig behandelt.

Trigger-Vertrauen bestimmt die Cache-Schreibrechte

Ordnen Sie Auslöser nach dem Vertrauen in den ausgeführten Code ein, nicht nach dem Namen des Events. Ein Push in einen geschützten Branch kann nach Review als vertrauenswürdig gelten. Ein Fork-PR bleibt dagegen nicht vertrauenswürdig, auch wenn er dieselbe Build-Datei wie ein interner Commit ausführt. Halten Sie diese Einstufung in der Workflow-Richtlinie fest, damit sie im Code-Review nicht jedes Mal neu ausgehandelt werden muss.

Bei pull_request_target ist besondere Vorsicht nötig. Dieser Auslöser läuft im Kontext des Basis-Repositorys und kann dadurch Zugriff auf Berechtigungen haben, die ein normaler Fork-PR nicht besitzt. Checken Sie dort nicht ungeprüft den PR-Code aus und führen Sie ihn nicht aus. Die GitHub-Anleitung zur sicheren Verwendung von pull_request_target beschreibt diese Vertrauensgrenze. Wenn ein privilegierter Folgejob Daten aus einem untrusted Job übernimmt, müssen auch Artefakte und sonstige übergebene Inhalte geprüft werden.

workflow_run verdient eine eigene Prüfung: Ein nachgelagerter Workflow kann mit Berechtigungen laufen, die dem vorherigen Workflow nicht zur Verfügung standen. Vertrauen Sie daher nicht automatisch einer Cache-Datei, einem Artefakt oder einem generierten Skript, nur weil es aus einem erfolgreichen Lauf stammt. Die Dokumentation zu auslösenden Events sollte gemeinsam mit den Cache-Regeln und der Berechtigungsdefinition ausgewertet werden.

Schreibzugriffe nicht vertrauenswürdiger PRs verhindern

Trennen Sie den schreibenden Pfad vom PR-Pfad. Ein nicht vertrauenswürdiger PR erhält read oder none; ein eigener Workflow für vertrauenswürdige Branches aktualisiert den Cache. Verwenden Sie keinen privilegierten Folgejob, der ungeprüfte Dateien aus dem PR-Lauf übernimmt und sie anschließend in einen für Release- oder Signierjobs erreichbaren Cache schreibt.

Prüfen Sie außerdem, ob Cache-Schlüssel tatsächlich voneinander getrennt sind. Ein Schlüssel sollte den relevanten Betriebssystem- und Toolchain-Kontext sowie die Abhängigkeitsdateien abbilden. Ein breiter Wiederherstellungsschlüssel kann zwar mehr Treffer liefern, erweitert aber auch den Kreis der Inhalte, die ein Job akzeptiert. Nutzen Sie Wiederherstellungspräfixe deshalb nur, wenn ein Treffer aus dieser Quelle für genau diesen Job vertretbar ist.

Ein Cache ist eine Eingabe in den Build, kein Beleg für eine vertrauenswürdige Herkunft. Behandeln Sie wiederhergestellte ausführbare Dateien, Skripte und generierte Build-Ausgaben so, als könnten sie verändert worden sein.

Cache-Inhalte, Schlüssel und Scopes begrenzen

Der Sicherheitsgewinn einer engen Berechtigung hängt davon ab, was im Cache liegt. Abhängigkeiten können ausführbare Inhalte enthalten; Build-Ausgaben können Skripte, Plugins oder andere Artefakte umfassen, die spätere Jobs verwenden. Speichern Sie keine Zugangsdaten, privaten Schlüssel, Signaturzertifikate oder andere Geheimnisse in einem Cache. Die GitHub-Dokumentation zum sicheren Umgang mit Dependency-Caches warnt vor dem Offenlegen sensibler Daten und beschreibt die Grenzen der Cache-Zugriffe.

Prüfen Sie bei jeder Cache-Definition diese Fragen:

  • Ist der Inhalt reproduzierbar aus vertrauenswürdigen Quellen erzeugbar?
  • Kann ein späterer, stärker privilegierter Job den Inhalt wiederherstellen?
  • Bezieht der Schlüssel alle Dateien ein, die die Abhängigkeiten oder Build-Schritte beeinflussen?
  • Akzeptiert ein Wiederherstellungsschlüssel Inhalte aus einem weiter gefassten Scope?
  • Wird die wiederhergestellte Datei ausgeführt oder in einen Signier- beziehungsweise Release-Schritt übernommen?

Ein Cache-Miss ist in der Regel eine operative Unannehmlichkeit, kein Grund, die Vertrauensgrenze aufzuweichen. Definieren Sie für nicht verfügbare oder nicht passende Caches einen kontrollierten Fallback: Abhängigkeiten neu beziehen, den Build ohne Cache fortsetzen oder den Job stoppen, wenn Integritätsprüfungen nicht erfüllt sind. Der Ablauf sollte vorhersehbar sein und darf bei einem Cache-Miss nicht stillschweigend auf einen unsicheren Schlüssel oder eine gemeinsame lokale Arbeitsumgebung ausweichen.

Cache-Modus und persistenter self-hosted Mac Runner sind getrennte Schutzebenen

Nein. cache-mode steuert den Zugriff auf den Actions-Cache. Es löscht weder das lokale Arbeitsverzeichnis noch Toolchain-Zustände, Prozesse, Schlüsselbunddaten, Umgebungsvariablen oder gespeicherte Zugangsdaten auf einem persistenten Mac. Ein Workflow mit none kann weiterhin auf lokale Reste eines vorherigen Jobs treffen, wenn die Runner-Umgebung nicht bereinigt oder neu aufgebaut wird.

Das ist besonders relevant für self-hosted Mac Runner, auf denen nicht vertrauenswürdige Pull Requests und vertrauliche Release-Jobs nacheinander ausgeführt werden könnten. Die GitHub-Empfehlungen zur sicheren Nutzung selbst gehosteter Runner weisen auf das Risiko hin, nicht vertrauenswürdigen Workflow-Code in einer Umgebung mit Zugriff auf interne Ressourcen oder Geheimnisse auszuführen. Ein Cache-Modus ändert daran nichts.

Prüfen Sie deshalb zwei getrennte Schutzebenen:

  • Remote-Cache: Wer darf Inhalte wiederherstellen oder speichern, und welche Scopes sind erreichbar?
  • Mac-Host: Welche Jobs dürfen auf dieselbe lokale Umgebung zugreifen, und welche Rückstände bleiben zwischen Jobs bestehen?

Wenn Sie auf dem Host keine verlässliche Bereinigung nachweisen können, führen Sie Jobs mit unterschiedlichen Vertrauensstufen nicht auf derselben persistenten Umgebung aus. Trennen Sie Runner-Gruppen nach Aufgabe und Berechtigung, halten Sie Signaturgeheimnisse aus niedrig vertrauenswürdigen Jobs heraus und planen Sie für besonders sensible Aufgaben eine frische oder neu aufgebaute Umgebung ein. Die Entscheidung zwischen physisch dediziertem Mac und Virtualisierung betrifft eine andere Architekturebene als die Cache-Berechtigung; dazu finden Sie eine ergänzende Einordnung zu Bare Metal und macOS-Virtualisierung.

Abnahmenachweise vor dem Rollout

Bevor Sie den neuen Modus breit ausrollen, testen Sie einen vertrauenswürdigen und einen nicht vertrauenswürdigen Pfad getrennt. Verlassen Sie sich nicht allein auf den erfolgreichen Abschluss des Jobs: Ein erfolgreicher Build beweist weder, dass ein Cache-Schreibversuch blockiert wurde, noch dass der Mac nach Ende des Jobs frei von Rückständen ist.

Arbeiten Sie diese Prüfliste im Review und in einem kontrollierten Testlauf ab:

  • [ ] Ordnen Sie jedem Workflow-Auslöser eine dokumentierte Vertrauensstufe zu.
  • [ ] Setzen Sie den Cache-Modus explizit; halten Sie den erwarteten effektiven Wert fest.
  • [ ] Prüfen Sie in den Logs, ob Wiederherstellung und Speicherung jeweils erlaubt, abgelehnt oder übersprungen wurden.
  • [ ] Verifizieren Sie Cache-Schlüssel, Wiederherstellungspräfixe und den zugänglichen Branch-Scope.
  • [ ] Prüfen Sie Workflow-Berechtigungen und trennen Sie Cache-Zugriff von Token- und Geheimniszugriff.
  • [ ] Führen Sie einen vertrauenswürdigen Build aus und bestätigen Sie, dass nur der vorgesehene Workflow den Cache aktualisiert.
  • [ ] Führen Sie einen nicht vertrauenswürdigen PR-Pfad aus und bestätigen Sie, dass er keinen Cache für einen vertrauenswürdigen Job verändern kann.
  • [ ] Prüfen Sie auf dem Mac, ob Arbeitsbereich, Toolchain-Zustand und temporäre Zugangsdaten nach dem Job entfernt oder isoliert sind.
  • [ ] Testen Sie den Fehlerfall: Bei Cache-Miss oder verweigertem Schreibzugriff muss der Job kontrolliert fortsetzen oder abbrechen.
  • [ ] Halten Sie fest, wer die Ergebnisse geprüft und die Freigabe erteilt hat.

Bewerten Sie das Ergebnis als freigegeben, wenn Cache-Rechte, Workflow-Berechtigungen und Host-Isolation zusammenpassen. Erteilen Sie eine Freigabe mit Auflagen, wenn die Cache-Seite sauber ist, aber Bereinigung oder Trennung noch nachgewiesen werden muss. Vergeben Sie keine Freigabe, wenn ein nicht vertrauenswürdiger Job Inhalte in einen Cache schreiben kann, den ein privilegierter Job später konsumiert, oder wenn auf einem persistenten Mac vertrauliche Rückstände nicht ausgeschlossen sind.

Freigabeentscheidung für Plattform, Sicherheit und Entwicklung

Vereinbaren Sie eine gemeinsame Richtlinie mit drei klaren Aussagen: Nicht vertrauenswürdige Eingaben erhalten standardmäßig read oder none; Cache-Schreibrechte liegen bei einem getrennten, vertrauenswürdigen Workflow; Produktionssignierung und niedrig vertrauenswürdige Aufgaben teilen keine ungesicherte Umgebung. Weichen Sie davon nur mit dokumentiertem Bedarf, überprüftem Datenfluss und nachvollziehbaren Tests ab.

Für einen Pilotbetrieb genügt es nicht, dass ein einzelner Build erfolgreich ist. Die Plattformverantwortlichen sollten die wirksamen Cache-Einstellungen belegen, das Sicherheitsteam die Trigger- und Geheimnisgrenzen prüfen und die iOS-Verantwortlichen den Umgang mit wiederhergestellten Inhalten bis zum Signierschritt nachvollziehen können. Erst wenn diese Nachweise zusammenpassen, ist eine Ausweitung auf weitere Teams vertretbar.

Wenn Ihre aktuelle Lösung PR-Code auf dauerhaft genutzten Macs ausführt, entstehen drei reale Schwachstellen: lokaler Zustand kann zwischen Jobs bestehen bleiben, gemeinsame Toolchains erschweren die Zuordnung von Veränderungen, und verbliebene Zugangsdaten können eine getrennte Cache-Berechtigung unterlaufen. Ein selbst betriebener Mac bleibt sinnvoll, wenn Sie dauerhafte Last, direkten Hardwarezugriff und eigene Betriebsverantwortung benötigen. Für einen zeitlich begrenzten CI-Pilot oder zusätzliche Testkapazität können Sie stattdessen ein Mac-Setup zur Miete prüfen; vergleichen Sie dabei Isolation, Bereinigung, Zugangsdatenverwaltung und Übergabeprozess, bevor Sie Aufgaben darauf verlagern. Die verfügbaren Angaben zu Mac-Knoten und Preisen können Sie auf der Übersichtsseite zu Bare-Metal-macOS prüfen.

Weitere Lektüre