IT-Admin.tech

CI/CD-Runner absichern: Credential-Isolation, sicheres Workspace-Cleanup und Schutz der Build-Kette

Architekturdiagramm einer CI/CD-Pipeline mit Ephemeral-VM-Runnern, OIDC-Tokenflow, HSM-basiertem Signierdienst und...
Diagramm zeigt Trennung: Ephemeral Runner, internes Mirror, Artefakt-Repository und HSM/Signierdienst — so minimieren Sie Blast Radius bei kompromittierten Builds.

CI/CD-Runner absichern ist kein Sicherheits-Hack, sondern eine nachhaltige Betriebsaufgabe: Runner ziehen Quellcode, bauen Artefakte und haben häufig Zugriff auf Credentials, Caches und das interne Netzwerk. Für Administratoren und Operatoren ist entscheidend, Angriffsflächen messbar zu reduzieren und klare Prüf- und Rückfallpfade zu haben. Dieser Leitfaden liefert konkrete Maßnahmen, Prüfschritte und Troubleshooting für Credential-Isolation, robustes Workspace-Cleanup und Schutz der Build‑Kette.

Warum Runner ein kritischer Angriffsvektor sind

Runner sind Ausführungsumgebungen für CI/CD-Jobs (Builds, Tests, Packaging). Ein kompromittierter Runner kann:

  • Secrets exfiltrieren (Tokens, SSH-Keys, Cloud-Credentials).
  • Artefakte verändern oder manipuliert signieren.
  • Cache-Poisoning durchführen und dadurch nachfolgende Builds beeinflussen.
  • Pivoting ins interne Netzwerk ermöglichen.

Wichtige Unterscheidung: trusted-Builds (z. B. geschützte Branches oder Releases) versus untrusted-Builds (forks, externe PRs, öffentliche Contributions). Für untrusted Builds muss die Betriebsannahme gelten: der Job ist potentiell bösartig.

Grundprinzipien: Minimalrechte, Isolation, Nachvollziehbarkeit

Betreiben Sie Härtung entlang dreier messbarer Ziele:

  • Isolationsziel: Kein Job darf State eines anderen Jobs sehen.
  • Credential-Ziel: Jobs erhalten nur minimal notwendige, bevorzugt kurzlebige Credentials.
  • Integritätsziel: Herkunft und Unveränderbarkeit von Abhängigkeiten und Artefakten sind nachvollziehbar.

Diese Ziele lassen sich operationalisieren, testen und auditieren.

Credential-Isolation: Umsetzung, Gründe und typische Fallen

Credential-Isolation bedeutet: keine statischen Allzweck-Tokens. Teilen Sie Identitäten nach Pipeline-Phase (Build, Package, Release, Deploy) und Kontext. Nutzen Sie kurzlebige Tokens (TTL in Minuten/Stunden) via OIDC, STS (Security Token Service) oder HashiCorp Vault-Leases. Kurzlebige Credentials begrenzen den Blast Radius bei Kompromittierung und vereinfachen Widerruf.

Technische Optionen und ihr Einsatz

OIDC (OpenID Connect) ist ein Protokoll zur Ausgabe von kurzlebigen Tokens; es verbindet CI-Systeme mit Cloud-IAM oder Vault ohne dauerhafte Secrets. KMS/HSM (Key Management Service / Hardware Security Module) speichert private Schlüssel außerhalb der Runner. Vault bietet dynamische Secrets (z. B. Datenbank-Credentials auf Lease-Basis). Jede Option hat Betriebsanforderungen: OIDC benötigt zuverlässige Token-Claims, Vault erfordert Hochverfügbarkeit und Access-Policies.

Beispiel: Vault-Policy für Package-Push

Hcl
# Vault policy (HCL) - erlaubt Token zum Schreiben in ein internes Artefakt-Repo
path "secret/data/ci/artifacts/*" {
  capabilities = ["create", "update", "read"]
}

Warum das funktioniert: Vault vergibt zeitlich begrenzte Tokens, und die Policy schränkt Pfade ein. Wann es scheitert: wenn Runner den Vault-Token persistieren (z. B. in Cache) oder Policies zu breit definiert sind.

Policy-begrenzte Signierung über Signierdienst

Private Signierschlüssel dürfen nicht auf normalen Runnern liegen. Ein Signierdienst (ein interner Service, der über KMS/HSM signiert) nimmt Artefakt-Hashes entgegen, prüft Policies (z. B. dass der Build von einem geschützten Branch stammt) und signiert dann. Die Signaturoperation benötigt separate Audit-Logs und strikte Authentifizierung.

CI/CD-Runner absichern: Isolation auf Infrastrukturebene

Wählen Sie Isolation nach Risiko und Wirtschaftlichkeit:

  • Host-Runner: Schnell, aber nur für fully-trusted Jobs.
  • Container-Runner: Gute Performance, aber nur mit rootless/strikten Mount-Policies.
  • Ephemeral VM/Instance-Runner: Höchste Isolation; pro Job frische VM oder Snapshot. Kosten höher, Sicherheit am höchsten.

Ephemeral-Runner sind besonders empfehlenswert für untrusted Builds: nach Beendigung wird die Instanz zerstört, damit Persistenz nicht möglich ist.

Beispiel: Kubernetes-Runner als Ephemeral-Job

Yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: runner-job-{{ .RunID }}
spec:
  template:
    spec:
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      containers:
      - name: builder
        image: registry.internal/runner-image:stable
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
      restartPolicy: Never
  backoffLimit: 0

Warum das hilft: Kubernetes erlaubt Namespaces, NetworkPolicies und Pod-Security-Kontexte zur Einschränkung. Achtung: fehlerhafte RBAC- oder Volume-Einstellungen können Isolation unterwandern.

Sicheres Workspace-Cleanup: Robust und manipulationsresistent

Ein fehlerhaftes Cleanup ermöglicht Persistenz. Probleme entstehen durch offene Handles, gemountete Dateisysteme, Symlink-Tricks und restriktive ACLs. Ein robustes Cleanup implementiert mehrere Schutzschichten: dedizierte Workspaces, Ownership-Normalisierung, –one-file-system beim Löschen und Prüfläufe mit Audit-Logging.

Linux: Erweitertes Cleanup inklusive Handle-Check

Shell
#!/usr/bin/env bash
set -euo pipefail
JOB_DIR="$1"
RUNNER_UID=1001
RUNNER_GID=1001

# 1) Prozesse beenden, die in JOB_DIR arbeiten
fuser -k -TERM -m "$JOB_DIR" || true
sleep 1
fuser -k -KILL -m "$JOB_DIR" || true

# 2) Ownership und Rechte normalisieren
chown -R "${RUNNER_UID}:${RUNNER_GID}" "$JOB_DIR" 2>/dev/null || true
chmod -R u+rwX,go-rwx "$JOB_DIR" 2>/dev/null || true

# 3) Prüfen auf Mountpoints im Jobdir
mountpoints=$(findmnt -n -o TARGET --target "$JOB_DIR" || true)
if [ -n "$mountpoints" ]; then
  echo "Found mounts: $mountpoints" >&2
  # Option: detach mounts safely or warn and abort
fi

# 4) Löschen sicher durchführen
rm -rf --one-file-system "$JOB_DIR"

Weshalb fuser nötig ist: Offene Dateihandles verhindern Löschung; Prozesse müssen sauber beendet werden. Scheitern kann das Skript, wenn ein Job Systemprozesse gestartet hat, die das Skript nicht terminieren darf—deshalb Logging und Warnstufen wichtig.

Windows: Handles, Reboot-Plan und Antivirus-Interaktion

Auf Windows sind Locks durch Dienste und AV üblich. Ergänzen Sie Cleanup mit Handle-Checks (Sysinternals Handle/Process Explorer), Retries und einem geplanten Reboot-Pfad, falls Löschung nicht möglich ist. Bloße Retries reichen bei hartnäckigen Locks nicht immer — dokumentieren Sie einen Rollback-Pfad.

Build-Kettensicherheit: Paketquellen, Caches und Signierung

Schützen Sie die Build-Kette durch Isolation von Paketquellen, Proxys mit Allow-Lists, kontrollierte Caches und unveränderliche Artefakt-Policies.

Interne Mirrors und Egress-Restriktion

Neben Allow‑Lists für Paketendpunkte sollten Runner nur definierten Egress haben: VCS, Mirror, Artefakt-Repo, KMS/Signierdienst. Egress-ACLs reduzieren Chancen für exfiltration/Zeichen zur Command-and-Control-Infrastruktur. Testen Sie Änderungen zunächst im Monitor-Mode (nur Logging) bevor Sie blocken.

Artefakt-Repo-Hardening

Setzen Sie Write-Policies (non-overwrite), Retention-Policies und require-signed-artifact-Flags, wenn Ihr Repo das unterstützt. Audit-Logs müssen zeigen, wer wann ein Artefakt veröffentlichte. Beispielregel: „Releases dürfen nur nach Signatur durch Signierdienst veröffentlicht werden“.

Cache-Strategien gegen Poisoning

Trennen Sie Caches nach Vertrauenszonen und Projekten. Vermeiden Sie shared writable caches für untrusted Jobs. Nutzen Sie TTL-Invalidierung und verzeichnete Cache-Hashes, um Poisoning zu erkennen.

Netzwerk- und Host-Härtung: konkrete Maßnahmen

Behandeln Sie Runner wie kritische Infrastruktur-Komponenten:

  • eigene Netzwerksegmente oder VLANs
  • definierte Egress-ACLs
  • Host-Firewall und Patchprozess
  • Monitoring und zentralisierte Logs

Beispiel: einfache iptables-Regel für Egress (VM-Runner)

Shell
# Erlaube nur DNS, HTTP(S) zu mirror.example und signing.example
iptables -A OUTPUT -m owner --uid-owner runner -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner runner -p tcp -d mirror.example --dport 443 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner runner -p tcp -d signing.example --dport 443 -j ACCEPT
iptables -A OUTPUT -m owner --uid-owner runner -j DROP

Warum das hilft: Selbst wenn ein Job versucht, bösartige Kommunikation aufzubauen, bleibt Egress begrenzt. Achtung: DNS-over-HTTPS und andere Umgehungswege können dies unterlaufen—testen und monitoren.

Testing, Audit und Validierung

Sichern Sie Maßnahmen durch automatisierte Tests und Audits:

  • Regelmäßige Audit-Jobs, die versuchen, aus einem Runner heraus nicht erlaubte Aktionen durchzuführen (nur im isolierten Testnetzwerk!).
  • Post-Job-Audits: Prüfe Workspace-Verbleib, offene Handles, aktive Prozesse.
  • Log-Analyse: Suche nach Token-Exfiltration oder ungewöhnlichen Egress-Verbindungen.

Beispiel-Testskript: Post-Cleanup-Validation

Shell
#!/usr/bin/env bash
# Prüft, ob ein Job-Verzeichnis nach Cleanup noch existiert
JOB_DIR="$1"
if [ -e "$JOB_DIR" ]; then
  echo "CLEANUP FAILED: $JOB_DIR still exists" >&2
  ls -la "$JOB_DIR" >&2
  exit 2
fi
# Prüfe auf aktive Prozesse des Runner-User
if pgrep -u runner >/dev/null; then
  echo "ACTIVE PROCESSES FOUND" >&2
  ps -u runner -o pid,cmd
  exit 3
fi
exit 0

Typische Stolperfallen und Troubleshooting

1) Geheimnisse versehentlich ins Build-Log

Ursache: Debug-Prints oder fehlendes Masking. Maßnahmen: CI-Log-Masking aktivieren, Sensible Variablen nicht als Plain-Text ausgeben. Prüfen Sie Logs automatisiert auf Muster (API-Keys, Bearer-Tokens) mit einem scanner-Job.

2) Privileged Container missbraucht

Ursache: Privilegierte Container oder Durchreichen von Docker-Socket. Maßnahme: rootless-Builds, keine Host-Socket-Mounts, Nutzung von Buildkit/remote daemon. Test: Job versucht, neue Container auf Host zu starten (nur in Testumgebung!).

3) Signierschlüssel auf Runner

Ursache: Praktikabilität statt Sicherheit — Teams legen Schlüssel lokal ab. Maßnahme: Signaturdienste zentralisieren, Schlüssel nur im HSM/KMS. Rückfall: Sofort Rotation und Invalidierung aller potentiell kompromittierten Schlüssel.

Rollback- und Notfallstrategie

Führen Sie Änderungen stufenweise ein:

  1. Monitor-Mode: nur Logging, keine Blockade.
  2. Schrittweises Schließen von Egress/Policy-Bereichen.
  3. Parallelbetrieb alter und neuer Runner-Pools; Umschaltung per Feature-Flag/Route.
  4. Break-Glass-Tokens für Notfälle mit Kurzlebigkeit und Audit.

Wichtig: dokumentieren Sie die Rückrollschritte und testen Sie sie regelmäßig in einem isolierten Testlauf.

Praxis-Checkliste: Umsetzung in 90–180 Minuten

  • Aktive Tokens inventarisieren und für jede Pipeline-Phase Rechte prüfen.
  • Untrusted Jobs auf separate Runner-Pools oder Ephemeral-VMs migrieren.
  • Cleanup-Skripte erweitern: process-kill, chown, chmod, –one-file-system, Post‑Validation.
  • Signierprozess auditieren und Schlüsselbewegung in HSM/KMS planen.
  • Egress-ACLs in Monitor-Mode anlegen und Traffic beobachten.
  • Audit-Job: Versuche, aus Runner unautorisierte Aktionen auszuführen (isoliert).

Fazit

CI/CD-Runner absichern bedeutet, Praktikabilität mit messbarer Sicherheit zu verbinden. Priorisieren Sie Credential-Trennung nach Pipeline-Phase (mit kurzlebigen Tokens), garantiertes Workspace-Cleanup (oder Ephemeral-Runner) und Signierung über Signierdienst bzw. HSM/KMS. Ergänzen Sie das Ganze mit Egress-Restriktionen, Monitoring und regelmäßigen Audit-Tests. Mit schrittweiser Einführung, Monitor-Mode-Phasen und getesteten Rückfallpfaden bleibt Sicherheit handhabbar und betriebssicher.

FAQ

Was ist der größte Fehler beim Absichern von CI/CD-Runnern?

Der häufigste Fehler ist ein dauerndes, breit berechtigtes Token für alle Pipeline-Phasen. Ein kompromittierter Job erhält damit zu viel Macht. Besser ist die Trennung nach Phase (Build, Package, Release, Deploy) und kurzlebige, kontextgebundene Tokens.

Reicht ein Container als Isolation für untrusted Builds?

Ein Container allein reicht nur, wenn Privilegien, Mounts und Netzwerk strikt beschränkt sind. Besonders gefährlich sind privileged Container oder das Durchreichen des Docker-Sockets. Für untrusted Builds sind ephemeral VMs oder stark isolierte Kubernetes-Jobs robuster.

Wie stelle ich sicher, dass Workspace-Cleanup wirklich funktioniert?

Nutzen Sie dedizierte Job-Workspaces, normalize Ownership/Permissions vor dem Löschen und löschen Sie mit –one-file-system. Bei Windows stoppen Sie Prozesshandles des Job-Users und arbeiten mit Retries. Automatisierte Post‑Job-Audits prüfen, ob Reste verbleiben.

Warum darf der private Signierschlüssel nicht auf dem Runner liegen?

Liegt der Schlüssel auf Standard-Runnern, kann ein kompromittierter Job manipulierte Artefakte signieren. Besser ist Signatur via HSM/KMS oder ein separater Signierdienst, der nur in konkreten, policy‑geprüften Kontexten signiert.

Wie gehe ich mit Performance-Einbußen durch stärkere Isolation um?

Trennen Sie Caches nach Vertrauenszonen und Projekten, nutzen Sie interne Mirrors und warm-started Runner‑Images (Snapshots). So erhalten Sie Performance, ohne Cache‑Poisoning-Risiken einzugehen.

Welche Prüfungen sollten in einem Audit-Job für Runner enthalten sein?

Audit-Jobs sollten versuchen, nicht autorisierte Egress-Verbindungen aufzubauen, Schreibzugriff auf andere Workspaces zu erlangen, Zugriff auf Signier-APIs ohne gültige Claims zu testen und verifizieren, dass Post-Cleanup keine Dateien oder Prozesse zurücklässt. Diese Tests nur in isolierten Umgebungen laufen lassen.

CI/CD-Runner absichern: Betrieb, Monitoring und Integration

Technische Maßnahmen sind nur so gut wie ihr Betrieb. Planen Sie Monitoring, Metriken und Integrationen bereits bei der Einführung von Runner-Härtungen ein, damit Sicherheit wiederholbar und messbar bleibt.

Wichtige Metriken und Alerts:

  • Cleanup-Failure-Rate: Anteil Jobs, bei denen Post-Job‑Validation fehlgeschlagen ist. Schwellenwert definieren und Alarm auslösen, bevor Aufräumdefizite zur Persistenz führen.
  • Vault-Lease‑Errors und OIDC-Token‑Failures: Signalisiert Probleme bei Kurzzeit‑Credentials oder fehlerhafte Claims.
  • Ungewöhnliche Egress-Verbindungen pro Runner-Pool: plötzliche Steigerungen deuten auf Exfiltration oder Umgehungsversuche hin.
  • Signatur‑Anfragen pro Stunde und Signier‑Fehler: Abweichungen können auf kompromittierte Pipelines oder Policy‑Fehler hinweisen.

Integrationshinweise:

  • IAM/IdP: Binden Sie CI als OAuth/OIDC-Client an bestehende Identity‑Provider (z. B. AD, Okta). So bleiben Audit und Benutzerlebenszyklus zentral steuerbar.
  • Secrets-Backends: Nutzen Sie Vault/KMS dynamisch; automatisieren Sie Lease‑Erneuerung und Rotation. Dokumentieren Sie Notfall‑Rotationen und testen Sie den Key‑Revocation‑Pfad.
  • Artefakt-Repository: Ergänzen Sie Signing‑Policies um Attestations (Build‑Metadaten, SBOM). Das macht Herkunft prüfbar und erleichtert Incident‑Analysen.

Runbook- und Rückfallpraxis:

  • Erstellen Sie ein kurzes Runbook: Schritte zum Isolieren eines Runner‑Pools, Schlüsselrotation, Disable‑Switch für Signierdienst und Rollback auf warm‑standby‑Runner.
  • Führen Sie regelmäßige Chaos‑Tests in einer Testzone durch (Cleanup-Fail, Egress-Block) und bewerten Sie Betriebsprozesse anhand konkreter SLAs.

Fazit: Betrieb und Integration sind keine Nachgedanken. Gute Metriken, automatisierte Rotation sowie abgestimmte Runbooks machen CI/CD‑Sicherheit belastbar und im Alltag handhabbar.

Für dieses Thema sind auch Supply-Chain-Security und Build-Kette Schützen wichtig. Der Beitrag ordnet diese Aspekte verständlich ein und zeigt, worauf es im Alltag ankommt.