Die Sicherheitsarchitektur von GitHub Actions steht und fällt mit der Konfiguration auf Repository-Ebene. Während die Workflows selbst definieren, was ausgeführt wird, bestimmen die Settings, ob und unter welchen Bedingungen diese Ausführung überhaupt stattfinden darf. Diese Trennung ist bewusst gewählt: Sie verhindert, dass ein kompromittierter Workflow-Code seine eigenen Ausführungsrechte erweitern kann.
Die Einstellungen greifen dabei auf verschiedenen Ebenen – vom
grundsätzlichen An/Aus-Schalter über die Kontrolle erlaubter
Action-Quellen bis hin zu granularen Berechtigungen für das
GITHUB_TOKEN. Besonders in Organisationen entsteht dabei
ein Hierarchiesystem: Enterprise-Richtlinien schränken
Organisations-Einstellungen ein, diese wiederum begrenzen
Repository-Konfigurationen.
Der Zugang zu den relevanten Einstellungen erfolgt über
Settings → Actions → General im
jeweiligen Repository. Hier findet sich zunächst die Section “Actions
permissions”, die über drei Optionen verfügt:
Disable Actions schaltet GitHub Actions für das Repository komplett ab. Kein Workflow wird ausgeführt, keine Action kann aufgerufen werden. Diese Option eignet sich für Repositories, die zwar Code bereitstellen, aber keine Automatisierung benötigen – etwa reine Dokumentations-Repositories oder archivierte Projekte.
Allow all actions and reusable workflows ist die permissive Standardeinstellung. Workflows können jede beliebige Action aus jedem öffentlichen Repository nutzen. Für kleinere Projekte oder Entwicklungsumgebungen ist dies praktikabel, in produktiven Umgebungen jedoch ein Sicherheitsrisiko: Ein kompromittiertes oder bösartiges Action aus einem Drittanbieter-Repository könnte ungehindert ausgeführt werden.
Allow [OWNER], and select non-[OWNER], actions and reusable workflows aktiviert den restriktiven Modus und öffnet damit ein mehrstufiges Filtersystem. Diese Option erlaubt grundsätzlich alle lokalen Actions aus dem eigenen Repository, während externe Actions explizit freigegeben werden müssen.
Ein praktisches Szenario: Ein Unternehmen entwickelt eigene Actions
in einem zentralen Repository company/actions.
Produktions-Repositories sollen ausschließlich diese verwenden dürfen.
Die Konfiguration würde dann lokale Actions plus
company/actions/* erlauben, alle anderen blockieren.
Der restriktive Modus eröffnet drei zusätzliche Kontrollmechanismen, die kombinierbar sind:
Allow actions created by GitHub gibt Actions aus den
Organisationen actions und github frei – also
Standardaktionen wie actions/checkout oder
actions/setup-node. Diese Checkbox ist häufig aktiviert, da
die meisten Workflows auf diese fundamentalen Bausteine angewiesen sind.
GitHub verifiziert diese Actions selbst, sodass das Vertrauensniveau
hoch ist.
Allow Marketplace actions by verified creators erweitert die Freigabe auf Actions von verifizierten Marketplace-Partnern. Ein Verifikations-Badge zeigt im Marketplace an, dass GitHub die Identität des Creators geprüft hat. Dies bietet eine Mittelweg zwischen vollständiger Öffnung und manueller Einzelfreigabe.
Allow specified actions and reusable workflows ist der präziseste Kontrollmechanismus. Hier werden Actions und Workflows über ein Pattern-Matching-System individuell freigegeben:
| Pattern | Bedeutung | Beispiel |
|---|---|---|
owner/repo@ref |
Spezifische Action in bestimmter Version | actions/checkout@v4 |
owner/repo@sha |
Action mit fixiertem Commit-SHA | actions/checkout@a824... |
owner/* |
Alle Actions einer Organisation | hashicorp/* |
*/repo* |
Alle Repositories mit Name-Prefix | */terraform-* |
owner/*, !owner/blocked |
Mit Ausnahme | myorg/*, !myorg/experimental |
Die Syntax für reusable Workflows ist analog, enthält aber den
vollständigen Pfad:
owner/repo/.github/workflows/workflow.yml@v1.
Ein ausgeklügeltes Beispiel könnte so aussehen:
actions/*,
hashicorp/*,
octo-org/*,
!octo-org/deprecated-action@*,
*/terraform-*@*
Diese Konfiguration erlaubt alle GitHub-Actions, alle
HashiCorp-Actions, alle Actions der Organisation octo-org
(außer deprecated-action) sowie alle Repositories, deren
Name mit terraform- beginnt, unabhängig vom Owner.
Die Reihenfolge ist wichtig: Allow-Rules werden zuerst ausgewertet,
dann Deny-Rules. Ein ! blockiert also selbst dann, wenn
eine allgemeinere Regel bereits matchen würde.
In Organisationen und Enterprises entsteht eine hierarchische Konfigurationskaskade. Eine restriktive Einstellung auf höherer Ebene kann nicht durch permissivere Einstellungen auf niedrigerer Ebene überschrieben werden.
Wenn die Enterprise-Ebene beispielsweise festlegt, dass nur Actions von GitHub und verifizierten Creators erlaubt sind, kann eine Organisation diese Regel verschärfen (z.B. nur GitHub-Actions), aber nicht lockern (z.B. alle Actions erlauben).
In der Repository-Oberfläche wird dies visuell deutlich: Nicht verfügbare Optionen sind ausgegraut und ein Hinweistext erklärt: “This setting is controlled by your organization policy.”
Diese Hierarchie hat einen praktischen Grund: Zentrale Security-Teams können unternehmensweite Sicherheitsstandards durchsetzen, ohne auf die Kooperation einzelner Entwicklungsteams angewiesen zu sein. Ein typisches Pattern ist:
Actions und reusable Workflows in privaten Repositories sind standardmäßig nur innerhalb dieses Repositories nutzbar. Dies schützt proprietären Code, verhindert aber auch die Wiederverwendung über Repository-Grenzen hinweg.
Die “Access”-Einstellung unter Actions →
General ändert dies:
Not accessible ist die Standardeinstellung. Die Actions bleiben privat.
Accessible from repositories owned by ‘USERNAME’
(bei persönlichen Repositories) erlaubt die Nutzung in allen privaten
Repositories desselben Benutzers. Ein typischer Use-Case: Ein Entwickler
erstellt ein zentrales my-actions-Repository mit Workflows
für verschiedene private Projekte.
Accessible from repositories in the ‘ORGNAME’ organization (bei Organisations-Repositories) öffnet die Actions für alle privaten Repositories innerhalb der Organisation. Dies ist das Standardmuster für zentrale Action-Bibliotheken in Unternehmen.
Wichtig: Die Freigabe gilt nur für private Repositories. Öffentliche Repositories können ohnehin auf alle öffentlichen Actions zugreifen. Umgekehrt können öffentliche Repositories standardmäßig nicht auf private Actions zugreifen – selbst wenn diese “accessible” markiert sind.
Die Konfiguration erfolgt auf Seiten des Action-Repositories, nicht des konsumierenden Repositories. Dies folgt dem Prinzip, dass der Action-Owner kontrolliert, wer seine Arbeit nutzen darf.
Jeder Workflow-Run erhält automatisch ein kurzlebiges Token über das
Secret GITHUB_TOKEN. Dieses Token ermöglicht API-Zugriffe
auf das eigene Repository, ohne dass zusätzliche Credentials hinterlegt
werden müssen.
Die Default-Permissions für dieses Token werden auf Repository-Ebene unter “Workflow permissions” konfiguriert:
Read and write permissions ist der permissive Modus. Das Token erhält Lese- und Schreibzugriff auf die meisten API-Scopes – einschließlich der Möglichkeit, Code zu pushen, Releases zu erstellen oder Issues zu manipulieren. Für viele CI/CD-Workflows ist dies erforderlich, beispielsweise wenn Build-Artefakte in Releases hochgeladen werden sollen.
Read repository contents and packages permissions ist die restriktive Variante. Das Token darf nur lesen, kann aber keine Änderungen vornehmen. Dies folgt dem Principle of Least Privilege: Ein Test-Workflow, der lediglich Code auscheckt und Tests ausführt, benötigt keine Schreibrechte.
Eine weitere Checkbox steuert spezifisch Pull-Request-Operationen:
Allow GitHub Actions to create and approve pull requests erlaubt oder verbietet, dass Workflows Pull Requests erstellen oder approven. Dies verhindert, dass ein Workflow einen eigenen PR erstellt und sich selbst grünes Licht gibt – eine potenzielle Backdoor für Code-Änderungen ohne Review.
Die Standardeinstellung ist deaktiviert: Workflows dürfen keine PRs approven. Dies ist sinnvoll, da Approvals typischerweise menschliches Urteilsvermögen erfordern.
Die Repository-Einstellung definiert nur den Default. Einzelne
Workflows können individuellere Permissions im
permissions-Schlüssel der Workflow-Datei festlegen:
permissions:
contents: read
pull-requests: write
issues: writeDiese Deklaration überschreibt die Repository-Defaults für diesen spezifischen Workflow. Das ermöglicht granulare Kontrolle: Test-Workflows mit read-only, Deployment-Workflows mit erweiterten Rechten.
Eine Faustregel: Repository-Defaults sollten restriktiv sein (read-only), einzelne Workflows erweitern ihre Rechte explizit nach Bedarf. Dies macht Berechtigungen transparent und verhindert, dass vergessene alte Workflows unnötig hohe Privilegien haben.
Public Repositories stehen vor einem Dilemma: Einerseits sollen externe Contributors leicht Pull Requests erstellen können, andererseits dürfen deren Workflows nicht unbegrenzt auf Repository-Ressourcen und Secrets zugreifen.
GitHub löst dies über ein Approval-System. Unter “Fork pull request workflows” stehen drei Policies zur Auswahl:
Require approval for first-time contributors who are new to GitHub verlangt Approval nur von Nutzern, die sowohl GitHub-Neulinge sind als auch noch nie etwas zu diesem Repository beigetragen haben. Dies ist die lockerste Variante und geeignet für Repositories mit aktivem, vertrauenswürdigem Contributor-Pool.
Require approval for first-time contributors verlangt Approval von allen, die noch keinen Commit oder PR in diesem Repository gemergt haben. Ein einziger gemergter Beitrag genügt danach für unbegrenzte weitere PRs. Dies ist die Balance zwischen Sicherheit und Workflow-Fluss.
Require approval for all external contributors ist die restriktivste Option: Jeder PR von jemandem außerhalb der Organisation braucht Approval. Dies eignet sich für hochsensible Projekte oder bei Missbrauchsverdacht.
Die Approval-Logik greift sowohl für den PR-Author als auch für den Actor des auslösenden Events. Wenn also ein externer Contributor einen PR erstellt und ein Maintainer ein Re-Run triggert, wird geprüft, ob beide gemäß Policy zugelassen sind.
Ein häufiges Missverständnis: Die ersten beiden Policies bieten nur begrenzten Schutz. Ein Angreifer könnte zunächst einen harmlosen PR (etwa eine Tippfehler-Korrektur) einreichen, diesen mergen lassen und danach mit uneingeschränktem Workflow-Zugriff agieren. Die Dokumentation warnt explizit vor diesem Szenario.
Workflows, die über pull_request_target getriggert
werden, umgehen diese Approval-Mechanismen. Sie laufen im Kontext des
Base-Branch und haben Zugriff auf Secrets. Dies ist notwendig für
bestimmte Automatisierungen (etwa Bot-Comments), erfordert aber extreme
Vorsicht im Workflow-Code.
Private Repositories haben zusätzliche Fork-spezifische Einstellungen unter “Fork pull request workflows”:
Run workflows from fork pull requests erlaubt grundsätzlich Workflow-Ausführungen von Forks. Das Token ist dabei read-only und hat keinen Zugriff auf Secrets. Dies ermöglicht, dass externe Contributors Tests sehen können, ohne sensible Daten preiszugeben.
Send write tokens to workflows from pull requests gibt dem Token Schreibrechte. Dies ist riskant, da Fork-Code damit Repository-Änderungen vornehmen könnte.
Send secrets to workflows from pull requests macht alle Repository-Secrets verfügbar. Dies sollte nur in absolut vertrauenswürdigen Umgebungen aktiviert werden.
Require approval for fork pull request workflows fügt eine zusätzliche Approval-Schicht hinzu, selbst für Contributors mit write-Rechten.
Diese Optionen sind in privaten Repositories standardmäßig deaktiviert. Der Grund: Private Repositories enthalten oft proprietären Code oder Credentials. Ein Fork könnte diesen Code plus Secrets exfiltrieren.
Ein typisches Pattern für Open-Source-Projekte mit privater Entwicklung:
Dies trennt öffentliche Collaboration von sensitiven Deployment-Prozessen.
Unter “Actions permissions” findet sich die Checkbox Require actions to be pinned to a full-length commit SHA. Aktiviert man diese, müssen alle Action-Referenzen in Workflows über vollständige Commit-SHAs erfolgen:
# Erlaubt
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
# Nicht erlaubt
- uses: actions/checkout@v4
- uses: actions/checkout@mainDer Hintergrund: Tags und Branches sind veränderlich. Ein Angreifer, der Kontrolle über ein Action-Repository erlangt, könnte einen existierenden Tag auf bösartigen Code umbiegen. Der SHA hingegen referenziert einen unveränderlichen Commit.
Die Kehrseite: SHA-Referenzen sind wartungsintensiv. Security-Updates
einer Action erfordern manuelle SHA-Updates in allen konsumierenden
Workflows. Zudem sind SHAs unleserlich – ein Tag wie v4
kommuniziert Intent, ein SHA nicht.
Reusable Workflows können weiterhin über Tags referenziert werden.
Die Begründung: Reusable Workflows liegen in
.github/workflows/, deren Änderungen über den normalen
Review-Prozess laufen. Actions hingegen stammen oft aus externen
Repositories.
Ein pragmatischer Ansatz: SHA-Pinning für kritische Produktions-Workflows, Tag-Referenzen für Entwicklungs- und Test-Umgebungen.
GitHub speichert Workflow-Artefakte und Caches standardmäßig für eine bestimmte Dauer. Diese Einstellungen beeinflussen Storage-Kosten und Compliance-Anforderungen.
Artifact and log retention definiert, wie lange Build-Artefakte und Workflow-Logs aufbewahrt werden. Standardwert ist 90 Tage. Public Repositories können 1-90 Tage wählen, private Repositories 1-400 Tage.
Die Retention ist nicht retroaktiv: Eine Änderung auf 30 Tage löscht nicht sofort alle älteren Artefakte, sondern gilt nur für neu erstellte Objekte.
Cache settings steuern zwei Parameter:
Die Eviction-Strategie ist LRU (Least Recently Used): Erreicht die Gesamtgröße das Limit, werden die ältesten, am längsten nicht genutzten Caches gelöscht.
Ein typisches Szenario: Ein Node.js-Projekt cached
node_modules (500 MB) in 20 verschiedenen Branches. Nach
einigen Monaten sind 15 Branches inaktiv. Die 7-Tage-Retention löscht
deren Caches automatisch, wodurch nur noch 2,5 GB belegt sind.
| Retention-Typ | Standard | Public Repo Max | Private Repo Max | Besonderheit |
|---|---|---|---|---|
| Artifacts/Logs | 90 Tage | 90 Tage | 400 Tage | Nicht retroaktiv |
| Cache | 7 Tage | 90 Tage | 365 Tage | LRU-Eviction |
| Cache Size | 10 GB | 10.000 GB | 10.000 GB | Über Organisationslimit konfigurierbar |
Diese Einstellungen sind besonders relevant für Compliance: In regulierten Industrien müssen Build-Logs oft langfristig aufbewahrt werden (etwa für Audits). Die 400-Tage-Option deckt mehr als ein Jahr ab.
Umgekehrt: Projekte mit häufigen Builds und großen Artefakten profitieren von kürzeren Retentions, um Storage-Kosten zu minimieren. Ein Projekt, das täglich 1 GB Artefakte produziert, belegt bei 90 Tagen Retention 90 GB – bei 30 Tagen nur 30 GB.