Zum Inhalt springen
CASOON

Supply-Chain-Sicherheit automatisieren: Der praktische Werkzeugkasten

Von Dependabot bis SLSA: Wie Entwickler-Teams ihre Ökosysteme systematisch absichern

18 Minuten
Supply-Chain-Sicherheit automatisieren: Der praktische Werkzeugkasten
#Supply Chain Security #DevOps #Automatisierung #Best Practices
SerieSupply Chain Security
Teil 2 von 8

Im ersten Teil dieser Serie haben wir das Problem analysiert: 60 Milliarden Dollar Schaden durch Supply-Chain-Angriffe, 16.000 neue schädliche Pakete, kompromittierte GitHub Actions, bösartige VS Code Extensions. Die Zahlen sind eindeutig – Entwickler-Ökosysteme sind zur Frontlinie geworden.

Die gute Nachricht: Es gibt Lösungen, die funktionieren. Nicht theoretisch, sondern praktisch. Nicht utopisch teuer, sondern größtenteils kostenlos. Nicht komplett, aber wirksam.

Dieser Artikel zeigt konkret, wie Teams ihre Supply Chain absichern können – mit Tools, die 2025/2026 state-of-the-art sind, Konfigurationsbeispielen und realistischen Prioritäten.

Das Zwei-Säulen-Prinzip

Wirksame Supply-Chain-Sicherheit ruht auf zwei Säulen:

1. Automatisierung
Menschen machen Fehler. Müdigkeit, Review-Fatigue, Zeitdruck – alles führt zu übersehenen Risiken. Automatisierung fängt ab, was Menschen übersehen.

2. Menschliche Kontrolle
Automatisierung kann Muster erkennen, aber nicht verstehen. Kritische Entscheidungen – „Ist dieser Code vertrauenswürdig?” – erfordern Kontext und Urteilsvermögen.

Die Kunst liegt darin, beides richtig zu kombinieren.

Ebene 1: Dependency Management automatisieren

Die Werkzeuge im Vergleich

Dependabot (GitHub, kostenlos)

  • Vorteile: Zero Config, direkt in GitHub integriert, Security Alerts inklusive
  • Nachteil: Ein PR pro Dependency (bei 100 Dependencies = 100 PRs)
  • Wann: Kleine Projekte, GitHub-exklusiv, einfacher Einstieg

Renovate (Mend.io, Open Source)

  • Vorteile: Über 90 Package Manager, automatisches Grouping, Monorepo-Support, Multi-Plattform (GitHub, GitLab, Bitbucket)
  • Nachteil: Mehr Konfigurationsaufwand
  • Wann: Größere Teams, komplexe Projekte, präzise Kontrolle gewünscht

Praxis-Tipp: Viele Teams nutzen beide: Dependabot für Security Alerts, Renovate für reguläre Updates.

Renovate: Minimale Konfiguration für Maximum Impact

{
  "extends": ["config:recommended"],
  "schedule": ["before 4am on Monday"],
  "groupName": "all dependencies",
  "separateMajorMinor": true,
  "rangeStrategy": "bump",
  "automerge": true,
  "automergeType": "pr",
  "automergeStrategy": "squash",
  "packageRules": [
    {
      "matchUpdateTypes": ["minor", "patch"],
      "automerge": true
    },
    {
      "matchUpdateTypes": ["major"],
      "automerge": false,
      "labels": ["breaking-change"]
    }
  ]
}

Was das tut:

  • Wöchentlicher Check (Montag, 4 Uhr morgens)
  • Gruppiert alle Dependencies in einem PR
  • Auto-Merge für Minor/Patch (nach erfolgreichen Tests)
  • Manuelle Review für Major-Updates

Socket.dev: Echtzeit-Malware-Detection

Socket verwendet KI-gestützte Malware-Scanner und erkennt schädliche Pakete bevor sie installiert werden.

Verfügbare Tools (alle kostenlos):

  1. Socket GitHub App
    Scannt Pull Requests in Echtzeit. Warnt vor:

    • Typosquatting (ähnliche Paketnamen)
    • Credential Theft-Patterns
    • Obfuscation
    • Verdächtigen Netzwerk-Calls
  2. Socket CLI
    Drop-in Replacement für npm install:

    npx @socketsecurity/cli npm install

    Blockt Malware-Pakete direkt bei der Installation.

  3. Socket Browser Extension
    Alerts bei verdächtigen Paketen auf npmjs.com, zeigt Known-Malware-Verdicts.

  4. @npm_malware Twitter/X Feed
    Live-Alerts zu neu entdeckten schädlichen Paketen.

2025-Erfolge von Socket.dev:

  • Nx-Packages-Angriff erkannt (August 2025)
  • 27 npm-Pakete als Phishing-Infrastruktur identifiziert
  • Tinycolor/Shai-Hulud-Kampagne gestoppt

GitHub Advanced Security: Die Enterprise-Lösung

Ab April 2025 aufgeteilt in zwei Produkte:

GitHub Secret Protection ($19/Monat pro aktiver Committer)

  • Secret Scanning mit Push Protection
  • KI-gestützte Erkennung unstrukturierter Credentials (Passwörter)
  • Custom Patterns
  • Niedrige False-Positive-Rate

GitHub Code Security ($30/Monat pro aktiver Committer)

  • Code Scanning (CodeQL oder Third-Party)
  • Copilot Autofix für Code-Scanning-Alerts
  • Security Campaigns
  • Dependency Review Action

Neu: Auch für GitHub Team verfügbar (früher nur Enterprise).

Die 7-Tage-Regel implementieren

GitHub-Analysen zeigen: Eine 7-tägige Wartezeit für neue Paketversionen hätte 8 von 10 großen Supply-Chain-Angriffen 2025 verhindert.

Renovate-Konfiguration:

{
  "packageRules": [
    {
      "matchNewValue": "/.*/",
      "minimumReleaseAge": "7 days"
    }
  ]
}

Trade-off: 7 Tage später bedeutet auch 7 Tage später Security-Fixes. Abwägungssache.

Praxis-Tipp: Für kritische Security-Updates separate Rule mit "matchDatasources": ["security"]" und "minimumReleaseAge": "0 days".

Ebene 2: Pull Request Security

Das pull_request_target-Problem lösen

Das Problem: Workflows mit pull_request_target haben Zugriff auf alle Repository-Secrets und laufen Code aus Forks mit Schreibrechten.

Lösung: Workflow-Splitting

Unprivileged Workflow (läuft bei PR):

name: Test PR
on: pull_request

jobs:
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: read  # Nur lesen
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - run: npm ci
      - run: npm test
      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: test-results
          path: ./coverage

Privileged Workflow (läuft nach Test-Success):

name: Upload Results
on:
  workflow_run:
    workflows: ["Test PR"]
    types: [completed]

jobs:
  upload:
    runs-on: ubuntu-latest
    if: github.event.workflow_run.conclusion == 'success'
    permissions:
      contents: write  # Nur hier Schreibrechte
    steps:
      - name: Download results
        uses: actions/download-artifact@v4
      - name: Upload to service
        env:
          SECRET_TOKEN: ${{ secrets.UPLOAD_TOKEN }}
        run: ./upload.sh

Warum das funktioniert:

  • Untrusted Code läuft ohne Secrets
  • Privileged Workflow läuft nur nach erfolgreichen Tests
  • Secrets sind nie exponiert

Branch Protection Rules: Das Minimum

Aktivieren Sie mindestens:

  1. Require a pull request before merging

    • Anzahl Reviews: mindestens 1 (besser 2 für main)
    • Dismiss stale PR approvals when new commits are pushed
  2. Require status checks to pass before merging

    • Tests müssen grün sein
    • Build muss erfolgreich sein
  3. Require conversation resolution before merging

    • Alle Kommentare müssen addressed sein
  4. Do not allow bypassing the above settings

    • Auch Admins nicht (oder nur in Notfällen)
  5. Require signed commits (optional, aber empfohlen)

CODEOWNERS richtig nutzen

Problem: Ohne CODEOWNERS können beliebige Team-Mitglieder kritische Änderungen approven.

Lösung: .github/CODEOWNERS Datei:

# Default: Team Lead reviewed alles
* @team-lead

# Security-kritische Dateien
/.github/workflows/ @security-team @devops-lead
/Dockerfile @devops-lead
/docker-compose.yml @devops-lead

# Dependencies
/package.json @team-lead @security-team
/package-lock.json @team-lead @security-team
/go.mod @team-lead
/requirements.txt @team-lead

# Infrastruktur-Code
/terraform/ @infrastructure-team
/kubernetes/ @infrastructure-team

# Secrets/Config
*.env.example @security-team
*.secrets.* @security-team

Branch Protection Rule aktivieren:

  • Settings → Branches → “Require review from Code Owners”

Neu ab November 2025: Required review by specific teams in Rulesets – erlaubt Team-spezifische Review-Requirements für bestimmte Dateipfade.

Policy-as-Code mit OPA

Open Policy Agent (OPA) automatisiert Policy-Enforcement.

Beispiel: PR-Policy in Rego

package pullrequest

# Regel: PRs zu main müssen 2 Approvals haben
deny[msg] {
    input.base_branch == "main"
    count(input.approvers) < 2
    msg := "Pull requests to main require at least 2 approvals"
}

# Regel: Security-Files brauchen Security-Team-Approval
deny[msg] {
    some file
    input.changed_files[file]
    startswith(file, "security/")
    not has_security_approval
    msg := sprintf("Changes to %v require security team approval", [file])
}

has_security_approval {
    some approver
    input.approvers[approver]
    input.team_memberships[approver]["security-team"]
}

# Regel: Dependency-Änderungen brauchen Tests
deny[msg] {
    some file
    input.changed_files[file]
    file == "package.json"
    input.test_status != "passed"
    msg := "Dependency changes require passing tests"
}

GitHub Actions Integration:

- name: Check PR Policy
  uses: open-policy-agent/opa-action@v2
  with:
    policy: .github/policies/pr-policy.rego
    data: pr-context.json
    fail-defined: true

OPAL ermöglicht Git-basiertes Policy-Management: Policies in Git speichern, bei Änderungen automatisch auf alle OPA-Instanzen pushen.

Ebene 3: Build & Deployment absichern

SLSA Framework: Provenance als Vertrauensanker

SLSA (Supply-chain Levels for Software Artifacts, ausgesprochen “Salsa”) definiert vier Level für Build-Sicherheit.

SLSA Level 1: Provenance existiert

  • Build-Plattform generiert automatisch Metadaten
  • Zeigt: Wie wurde das Paket gebaut?
  • Wer hat es gebaut?
  • Aus welchem Quellcode?

SLSA Level 2: Provenance ist signiert

  • Build-Plattform signiert Provenance digital
  • Manipulation wird erkennbar
  • Build-System ist source-aware

SLSA Level 3: Build ist gehärtet

  • Build-Definitionen kommen aus Source
  • Gehärteter CI-Prozess
  • Isolation, Audit-Logs

Praktisch: SLSA Level 2 erreichen

GitHub Actions mit SLSA Generator:

name: Build with SLSA
on: push

permissions:
  contents: read
  id-token: write  # Für SLSA Provenance
  packages: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: npm run build
      
      - name: Generate SLSA Provenance
        uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0
        with:
          base64-subjects: "${{ needs.build.outputs.hashes }}"
          upload-assets: true

Was das bringt:

  • Verifiable Build Chain
  • Manipulation erkennbar
  • Trust, aber Verify

Sigstore/Cosign: Keyless Signing

Problem mit traditionellem Signing: Key-Management ist komplex, Keys müssen sicher gespeichert werden, Rotation ist aufwändig.

Sigstore-Lösung: Keyless Signing

  1. Authentifizierung via OIDC (Google, GitHub, Microsoft)
  2. Fulcio stellt kurzlebiges Zertifikat aus
  3. Ephemeral Key-Pair wird erzeugt
  4. Signing-Event wird in Rekor (Transparency Log) eingetragen
  5. Key wird verworfen

Container Image signieren:

# Installation
brew install cosign

# Keyless signing (GitHub Actions)
cosign sign --yes \
  --oidc-issuer=https://token.actions.githubusercontent.com \
  ghcr.io/myorg/myapp:v1.2.3

Verification:

cosign verify \
  --certificate-identity=user@example.com \
  --certificate-oidc-issuer=https://accounts.google.com \
  ghcr.io/myorg/myapp:v1.2.3

Adoption 2025:

  • Homebrew (Mai 2024)
  • PyPI (November 2024)
  • Maven Central (Januar 2025)
  • NVIDIA NGC (Juli 2025)

Cosign v3 (2025): Neues Bundle-Format, Trusted Root, Signing Config standardmäßig aktiviert.

Ebene 4: GitHub Actions härten

Action Pinning: Commit-Hash statt Tag

Problem: Tags sind mutable – sie können nachträglich auf schädlichen Code zeigen.

Schlecht:

- uses: actions/checkout@v4

Besser:

- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1

Automatisierung: Dependabot oder Renovate können auch Action-Hashes aktualisieren.

Permissions minimieren

Default (zu permissiv):

# Standardmäßig: read/write für viele Scopes

Explizit (sicher):

permissions:
  contents: read
  pull-requests: write  # Nur wenn nötig
  # Alles andere: implizit none

Pro Job:

jobs:
  test:
    permissions:
      contents: read  # Nur lesen
  deploy:
    permissions:
      contents: write  # Nur hier schreiben
      packages: write

Third-Party Actions auditieren

Risiken bei Third-Party Actions:

  • Kompromittierte Maintainer-Accounts
  • Nachträglich injizierter Schadcode
  • Zugriff auf Secrets

Auditierungs-Checkliste:

  • GitHub-Org verifiziert?
  • Wie viele Stars/Forks?
  • Letzte Aktivität?
  • Offene Security Issues?
  • Source Code gelesen?
  • Permissions angemessen?

Socket.dev scannt auch GitHub Actions auf verdächtige Patterns.

Reusable Workflows für Standard-Tasks

Statt dass jedes Team eigene Actions schreibt: Zentrale, auditierte Reusable Workflows.

# .github/workflows/reusable-test.yml
name: Reusable Test Workflow
on:
  workflow_call:
    inputs:
      node-version:
        required: true
        type: string

jobs:
  test:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci
      - run: npm test

Nutzung:

jobs:
  test:
    uses: ./.github/workflows/reusable-test.yml@main
    with:
      node-version: '20'

Vorteil: Ein Workflow auditieren, überall nutzen.

Ebene 5: IDE & Extensions kontrollieren

Policy für zugelassene Extensions

Problem: Jeder installiert, was ihm gefällt → unkontrollierte Angriffsfläche.

Lösung: Whitelist-Ansatz.

Beispiel approved-extensions.json:

{
  "approved": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "ms-python.python",
    "ms-vscode.cpptools",
    "redhat.vscode-yaml"
  ],
  "review-required": [
    "github.copilot",
    "continue.continue"
  ],
  "blocked": [
    "*.bitcoin-*",
    "*.crypto-miner"
  ]
}

Enforcement: Custom VS Code Extensions Marketplace (Enterprise) oder Policy-Check via Script.

Extension Permissions prüfen

Red Flags:

  • Syntax-Highlighting-Extension will Netzwerkzugriff
  • Theme will Dateisystem-Zugriff
  • Tool will auf alle Workspaces zugreifen

Beispiel: VS Code Extension Manifest prüfen

{
  "activationEvents": ["*"],  // ⚠️ Läuft immer
  "contributes": {
    "commands": [...],
    "configuration": {
      "properties": {
        "myext.serverUrl": {  // ⚠️ Remote Server?
          "type": "string"
        }
      }
    }
  }
}

Separate Profile für sensible Projekte

VS Code unterstützt Profile – nutzen Sie sie:

Profil “Standard”:

  • Alle gewohnten Extensions
  • Für normale Projekte

Profil “Secure”:

  • Minimale Extensions
  • Keine AI-Assistenten
  • Keine Remote-Connections
  • Für Kundenprojekte, Compliance-Code

Wechseln: Cmd/Ctrl + Shift + P → “Profiles: Switch Profile”

Ebene 6: Monitoring & Response

SBOM generieren und tracken

Was gehört in eine SBOM?

  • Name und Version aller direkten Dependencies
  • Name und Version aller transitiven Dependencies
  • Hashes (SHA-256)
  • Lizenzen
  • Known Vulnerabilities

Tools:

# CycloneDX (OWASP)
cyclonedx-npm --output-file sbom.json

# SPDX
spdx-sbom-generator

# Syft (für Container Images)
syft packages alpine:latest -o json > sbom.json

CISA-Anforderungen (August 2025): Aktualisierte Mindestanforderungen für SBOMs, maschinenlesbar, standardisiert.

EU Cyber Resilience Act: SBOM-Pflicht für Softwarehersteller ab 2026.

Dependency Graphs überwachen

GitHub zeigt Dependency Graph automatisch:

  • Settings → Code security and analysis → Dependency graph

Achten Sie auf:

  • Anzahl transitiver Dependencies (je mehr, desto höher das Risiko)
  • Veraltete Packages (über 2 Jahre alt)
  • Deprecated Packages
  • Packages mit Known Vulnerabilities

Anomalie-Detection in CI/CD

Verdächtige Patterns:

  • Build-Zeiten plötzlich länger (Mining?)
  • Unerwartete Netzwerk-Calls
  • Neue Dateien in Build-Output
  • Geänderte File-Hashes

Beispiel: File-Hash-Monitoring

- name: Check Build Artifacts
  run: |
    sha256sum dist/* > checksums.txt
    if ! diff checksums.txt expected-checksums.txt; then
      echo "::error::Build artifacts changed unexpectedly"
      exit 1
    fi

Incident Response Playbook

Was tun, wenn eine Dependency kompromittiert wurde?

  1. Sofort: Betroffene Version identifizieren (ist sie bei uns im Einsatz?)
  2. Audit: Logs prüfen (wann wurde sie installiert? Welche Secrets waren exponiert?)
  3. Rotate: Alle potenziell kompromittierten Secrets rotieren
  4. Update: Auf sichere Version aktualisieren
  5. Scan: Codebase auf Backdoors scannen
  6. Dokumentieren: Incident dokumentieren
  7. Learn: Was hätte es verhindert?

Template: Erstellen Sie ein Runbook mit konkreten Kommandos und Ansprechpartnern.

Sicherheit ist ein Prozess, kein Projekt

Die gute Nachricht: Wirksame Supply-Chain-Sicherheit ist machbar. Sie erfordert keine Millionen-Budgets und keine Armee von Security-Experten.

Die realistische Nachricht: Es ist kein Projekt mit Enddatum, sondern ein kontinuierlicher Prozess. Tools entwickeln sich weiter. Angreifer werden kreativer. Standards ändern sich.

Aber: Mit den richtigen Werkzeugen – Dependabot, Renovate, Socket.dev, GHAS, SLSA, Sigstore, OPA – lässt sich 90 % der Angriffe automatisiert verhindern. Die verbleibenden 10 % erfordern Wachsamkeit, gute Prozesse und ein Team, das versteht, warum das wichtig ist.

Der Kulturwandel ist genauso wichtig wie die Tools. Supply-Chain-Sicherheit ist kein Thema nur für das Security-Team. Es ist ein Thema für jeden, der Code schreibt, Dependencies hinzufügt oder Pull Requests reviewed.

Ein guter Einstieg: Dependabot aktivieren dauert 30 Sekunden. Branch Protection einrichten 5 Minuten. CODEOWNERS erstellen eine Stunde. Nicht alles auf einmal, aber jeder dieser Schritte macht Ihr Entwickler-Ökosystem ein Stück sicherer.

Die Werkzeuge existieren. Die Standards sind definiert. Was fehlt, sind Menschen, die beides verstehen und zusammenbringen – Entwicklung und Sicherheit. Genau hier entsteht ein neues Berufsfeld, das im dritten Teil dieser Serie beleuchtet wird.


Tools:

Guides:

Quellen