GitLab CI Secrets mit Vault statt nur Protected Variables verwalten
AI generated
CI/CD
.yml
GitLab · CI/CD · Security
GitLab CI Secrets mit Vault
statt nur Protected Variables: dynamische Credentials statt statischer Geheimnisse

GitLab Protected und Masked Variables sind der Standardweg, um Secrets in einer Pipeline zu verwenden, bleiben aber statische, langlebige Werte, die im schlimmsten Fall monatelang unveraendert im Umlauf sind. HashiCorp Vault geht ueber die native GitLab-CI-Integration einen anderen Weg: Credentials werden erst beim Pipeline-Lauf ausgestellt, sind kurzlebig und laufen automatisch ab. Dieser Artikel zeigt, wie die Integration technisch funktioniert, was sie gegenueber reinen Protected Variables gewinnt und wann sich der zusaetzliche Betriebsaufwand fuer ein Magento-Projekt tatsaechlich lohnt.

17 Min. Lesezeit HashiCorp Vault · Secrets Management GitLab CI/CD · OIDC

1. Das Grundproblem statischer CI/CD-Variablen

Jede in GitLab als Protected oder Masked markierte Variable ist im Kern ein einzelner Text-Wert, der in der Projekt- oder Gruppenkonfiguration gespeichert und bei jedem passenden Pipeline-Lauf in die Job-Umgebung geladen wird. Solange dieser Wert nicht manuell rotiert wird, bleibt er ueber Monate oder Jahre unveraendert derselbe, was ihn zu einem attraktiven Ziel macht: Wer ihn einmal abgreift, etwa ueber ein kompromittiertes Runner-System oder ein zu freizuegig konfiguriertes Debug-Logging, besitzt ein dauerhaft gueltiges Credential.

Fuer viele Anwendungsfaelle, etwa einen einzelnen API-Schluessel fuer einen unkritischen Drittanbieter-Service, ist dieses Risiko akzeptabel. Sobald es aber um Datenbank-Zugangsdaten, SSH-Deploy-Keys fuer Produktionsserver oder Composer-Auth-Tokens fuer kommerzielle Magento-Erweiterungen geht, wiegt ein dauerhaft gueltiges, statisches Geheimnis deutlich schwerer, weil ein einziger Leak potenziell unbegrenzt lange ausnutzbar bleibt, bis jemand die Rotation manuell anstoesst.

2. Wie GitLab Protected und Masked Variables funktionieren, und wo die Grenzen liegen

Protected Variables stehen ausschliesslich in Pipelines zur Verfuegung, die auf geschuetzten Branches oder Tags laufen, was verhindert, dass ein beliebiger Feature-Branch versehentlich Zugriff auf produktive Secrets erhaelt. Masked Variables wiederum sorgen dafuer, dass der Wert in den Job-Logs durch Sternchen ersetzt wird, sofern der Wert bestimmte Formatregeln erfuellt, etwa keine Zeilenumbrueche enthaelt und eine Mindestlaenge hat.

Beide Mechanismen schuetzen jedoch nur den Transportweg und die Sichtbarkeit, nicht die Lebensdauer des Geheimnisses selbst. Ein einmal in den Projekteinstellungen hinterlegter Datenbank-Benutzername mit Passwort bleibt exakt dieser eine Benutzer mit exakt diesem einen Passwort, unabhaengig davon, wie oft die Pipeline laeuft. Es gibt in der GitLab-Variable selbst keinen Mechanismus fuer Ablaufzeiten, automatische Rotation oder eine Protokollierung, welcher konkrete Pipeline-Lauf das Secret zu welchem Zeitpunkt tatsaechlich genutzt hat.

3. Was HashiCorp Vault grundsaetzlich anders macht

Vault verwaltet Geheimnisse nicht als statische Werte, sondern kann sie ueber sogenannte Secrets Engines dynamisch zur Laufzeit ausstellen. Bei der Database Secrets Engine etwa erzeugt Vault bei jeder Anfrage einen frischen Datenbank-Benutzer mit zufaellig generiertem Passwort und einer festgelegten Lease-Zeit, nach deren Ablauf Vault den Benutzer automatisch wieder aus der Datenbank entfernt, ganz ohne manuelles Eingreifen.

Dadurch veraendert sich das Sicherheitsmodell grundlegend: Selbst wenn ein Angreifer ein ausgestelltes Credential abgreift, ist es nach kurzer Zeit automatisch wertlos. Zusaetzlich fuehrt Vault ein vollstaendiges Audit-Log jeder Ausstellung und jedes Zugriffs, sodass sich im Nachhinein exakt nachvollziehen laesst, welche Pipeline zu welchem Zeitpunkt welches Credential erhalten hat, was fuer Compliance-Anforderungen wie PCI DSS oder ISO 27001 einen erheblichen Unterschied macht.

4. Die native GitLab Vault Integration ueber JWT/OIDC ID Tokens

Seit GitLab 15.7 lassen sich JWT-basierte ID-Tokens direkt in jedem Job erzeugen, die kryptografisch signiert sind und Claims wie Projekt, Branch und Pipeline-ID enthalten. Vault kann ueber seine JWT/OIDC-Auth-Methode so konfiguriert werden, dass es diesen Token verifiziert und darauf basierend, ganz ohne vorab in GitLab hinterlegtes statisches Vault-Token, eine kurzlebige Vault-Sitzung fuer genau diesen Job ausstellt.

Die Zuordnung, welche Vault-Policy ein Job erhaelt, erfolgt dabei ueber Bound Claims in Vault, etwa eine Einschraenkung auf ein bestimmtes GitLab-Projekt oder einen bestimmten geschuetzten Branch. Dadurch bekommt ein Job aus einem Feature-Branch automatisch weniger Rechte als ein Job, der auf dem geschuetzten main-Branch laeuft, ohne dass dafuer irgendwo ein separates, manuell verwaltetes Credential existieren muesste.


deploy_production:
  stage: deploy
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.mironsoft.internal
  variables:
    VAULT_ADDR: https://vault.mironsoft.internal
  secrets:
    DB_PASSWORD:
      vault:
        engine:
          name: database
          path: database
        path: creds/magento-readwrite
        field: password
      token: $VAULT_ID_TOKEN
  script:
    - bin/magento setup:upgrade --keep-generated
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'

5. Beispiel: Dynamische Datenbank-Credentials fuer den Deploy-Job

In der klassischen Variante wird ein einziger MySQL-Benutzer mit vollen Rechten dauerhaft als Protected Variable hinterlegt, der von jedem Deploy-Job verwendet wird. Mit der Vault Database Secrets Engine erzeugt Vault dagegen bei jedem Pipeline-Lauf einen frischen Benutzer, dessen Rechte exakt auf die fuer setup:upgrade noetigen Operationen begrenzt sind, und dessen Lease-Zeit typischerweise wenige Stunden betraegt, ausreichend fuer die Laufzeit des Deploy-Jobs, aber nicht laenger.

Der Job selbst muss dafuer kaum angepasst werden: Statt die Zugangsdaten aus einer vordefinierten Umgebungsvariable zu lesen, ruft das secrets:-Keyword in der Job-Definition die Werte direkt von Vault ab und stellt sie als Umgebungsvariable bereit, sodass bin/magento setup:upgrade unveraendert funktioniert, nur eben mit einem Credential, das nach Ablauf der Lease-Zeit automatisch nicht mehr funktioniert.


# Vault Database Secrets Engine fuer MySQL konfigurieren
vault secrets enable database

vault write database/config/magento-mysql \
    plugin_name=mysql-database-plugin \
    connection_url="{{username}}:{{password}}@tcp(db.internal:3306)/" \
    allowed_roles="magento-readwrite" \
    username="vault-admin" \
    password="initial-admin-password"

vault write database/roles/magento-readwrite \
    db_name=magento-mysql \
    creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; \
        GRANT SELECT, INSERT, UPDATE, DELETE ON magento.* TO '{{name}}'@'%';" \
    default_ttl="2h" \
    max_ttl="4h"

6. Betrieb: Policies, Auth-Methoden und Rotation im Alltag

Im Vault-Betrieb selbst sollten Policies so granular wie moeglich definiert werden, im Idealfall eine eigene Policy pro Pipeline-Zweck, etwa eine fuer Datenbank-Migrationen und eine separate fuer den Zugriff auf Composer-Auth-Tokens, statt einer einzigen, breiten Policy fuer alle CI-Jobs. Neben der JWT/OIDC-Methode unterstuetzt Vault auch AppRole-Auth, was fuer Runner-Umgebungen sinnvoll sein kann, in denen kein natives GitLab-JWT verfuegbar ist, etwa bei selbstgehosteten Runnern in isolierten Netzwerken.

Fuer statische Secrets, die aus technischen Gruenden nicht dynamisch ausgestellt werden koennen, etwa API-Schluessel externer SaaS-Dienste, bietet Vault ueber die KV-Secrets-Engine trotzdem einen zentralen, versionierten und auditierten Speicherort, der immerhin die Nachvollziehbarkeit erheblich verbessert, auch wenn die Lebensdauer des Wertes selbst weiterhin manuell rotiert werden muss.

7. Aufwand gegen Nutzen: Wann sich Vault fuer ein Magento-Projekt lohnt

Der Betrieb eines eigenen Vault-Clusters, inklusive Unsealing-Strategie, Hochverfuegbarkeit und Backup-Konzept, ist selbst ein nicht triviales Infrastrukturprojekt, das Personalzeit und laufenden Betriebsaufwand bindet. Fuer ein einzelnes kleines Magento-Projekt mit wenigen Entwicklern und ueberschaubarer Secrets-Anzahl steht dieser Aufwand haeufig in keinem guten Verhaeltnis zum Sicherheitsgewinn gegenueber sorgfaeltig verwalteten Protected Variables mit regelmaessiger manueller Rotation.

Sobald jedoch mehrere Teams, mehrere Magento-Instanzen oder strenge Compliance-Vorgaben wie PCI DSS im Spiel sind, kippt die Rechnung deutlich: Ein zentraler Vault-Cluster, der fuer alle Projekte gemeinsam betrieben wird, amortisiert sich schnell, weil die Betriebskosten auf viele Nutzer verteilt werden, waehrend der Sicherheitsgewinn durch kurzlebige Credentials und lueckenloses Audit-Log pro Projekt gleich bleibt.

8. Migrationsstrategie: Schrittweise von Protected Variables zu Vault

Ein sinnvoller Einstieg ist, nicht alle Secrets auf einmal umzustellen, sondern mit dem sensibelsten Wert zu beginnen, in einem Magento-Projekt haeufig die Datenbank-Zugangsdaten fuer den Produktions-Deploy-Job. Dieser eine Job wird auf die Vault-Integration umgestellt, waehrend alle anderen Jobs unveraendert mit Protected Variables weiterlaufen, sodass sich Erfahrung mit der Integration aufbauen laesst, ohne das gesamte Deployment auf einmal zu riskieren.

Erst wenn sich die JWT/OIDC-Integration im Produktivbetrieb bewaehrt hat, folgen schrittweise weitere Secrets wie Composer-Auth-Tokens oder SSH-Deploy-Keys. Die folgende Tabelle fasst zusammen, welche Eigenschaften Protected Variables und Vault jeweils mitbringen und wo die Grenze fuer eine sinnvolle Migration typischerweise verlaeuft.

9. Praxisempfehlung: Vault und Protected Variables gezielt kombinieren statt gegeneinander auszuspielen

In der Praxis ist die Entscheidung selten ein reines Entweder-oder. Fuer ein einzelnes kleines Magento-Projekt ohne dediziertes Betriebsteam bleiben sorgfaeltig gepflegte Protected und Masked Variables mit einer festen, dokumentierten Rotationsfrist, etwa vierteljaehrlich, meist die pragmatischere Wahl, weil sich der Betriebsaufwand eines eigenen Vault-Clusters kaum rechtfertigen laesst. Unkritische Werte wie ein API-Schluessel fuer einen externen Bilddienst muessen dabei nicht zwingend in Vault wandern, nur weil das Werkzeug technisch verfuegbar ist.

Sobald jedoch bereits ein Vault-Cluster fuer andere Projekte im Unternehmen betrieben wird oder mehrere Magento-Instanzen mit getrennten Produktions- und Staging-Datenbanken existieren, lohnt es sich, Vault konsequent als einzige Quelle der Wahrheit fuer alle sensiblen Credentials zu etablieren, statt fallweise zwischen beiden Ansaetzen zu wechseln. Diese Konsistenz erspart dem Team die wiederkehrende Diskussion, welches Secret welchen Schutzmechanismus verdient, und macht Audits gegenueber Kunden oder Zertifizierungsstellen deutlich einfacher.

Eigenschaft Protected/Masked Variables HashiCorp Vault Empfehlung
Lebensdauer des Secrets Statisch, bis manuell rotiert Dynamisch, automatischer Ablauf Vault fuer sensible Credentials
Audit-Log pro Zugriff Nicht vorhanden Vollstaendig, pro Ausstellung Vault bei Compliance-Pflicht
Betriebsaufwand Minimal Eigener Cluster noetig Protected Variables fuer kleine Projekte
Zugriffs-Scoping Protected Branch/Tag Feingranulare Policies je Job Vault bei mehreren Teams
Setup-Komplexitaet Wenige Minuten Mehrere Tage bis Wochen Schrittweise Migration

Mironsoft

CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung

Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?

Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.

Pipeline-Review

Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.

Zero-Downtime-Deployment

Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.

CI/CD-Automatisierung

Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.

10. Zusammenfassung

Vault statt Protected Variables: Das Wichtigste auf einen Blick

Kernproblem

Protected und Masked Variables sind statisch und langlebig, ein einmaliger Leak bleibt potenziell unbegrenzt lange ausnutzbar.

Was Vault liefert

Dynamisch ausgestellte, kurzlebige Credentials mit automatischem Ablauf und vollstaendigem Audit-Log ueber die Secrets Engine.

Technischer Weg

GitLab JWT/OIDC ID-Tokens authentifizieren Jobs gegenueber Vault, ganz ohne vorab hinterlegtes statisches Vault-Token.

Wann es sich lohnt

Bei mehreren Teams, mehreren Magento-Instanzen oder strengen Compliance-Vorgaben, nicht zwingend bei einem einzelnen kleinen Projekt.

11. FAQ: Vault statt Protected Variables: Das Wichtigste auf einen Blick

1Was ist der grundlegende Unterschied zwischen Protected Variables und Vault-Secrets?
Protected Variables sind statische Werte, die bis zur manuellen Rotation unveraendert bleiben. Vault kann Credentials dynamisch zur Laufzeit ausstellen, mit einer festgelegten Lease-Zeit, nach deren Ablauf sie automatisch ungueltig werden.
2Brauche ich fuer die Vault-Integration ein statisches Vault-Token in GitLab?
Nein. Ueber die JWT/OIDC-Auth-Methode authentifiziert sich der Job mit einem von GitLab pro Pipeline-Lauf erzeugten ID-Token direkt gegenueber Vault, ganz ohne ein vorab in GitLab hinterlegtes Vault-Token.
3Ab GitLab welcher Version funktionieren JWT/OIDC ID-Tokens?
Die id_tokens-Syntax fuer JWT-basierte ID-Tokens steht seit GitLab 15.7 zur Verfuegung. Fuer aeltere Versionen muss auf die frueher genutzte, mittlerweile veraltete CI_JOB_JWT-Variable zurueckgegriffen werden.
4Was passiert, wenn ein dynamisch erzeugter Datenbank-Benutzer nach Ablauf der Lease noch aktiv genutzt wird?
Vault entfernt den Benutzer nach Ablauf der Lease-Zeit automatisch aus der Datenbank, wodurch laufende Verbindungen mit einem Authentifizierungsfehler abbrechen koennen. Die Lease-Zeit sollte deshalb grosszuegig genug fuer die tatsaechliche Job-Laufzeit gewaehlt werden.
5Lohnt sich Vault fuer ein einzelnes, kleines Magento-Projekt?
In den meisten Faellen nicht. Der Betriebsaufwand fuer einen eigenen Vault-Cluster steht selten in gutem Verhaeltnis zum Sicherheitsgewinn, solange nicht mehrere Projekte oder strenge Compliance-Vorgaben den Aufwand rechtfertigen.
6Kann Vault auch statische Secrets verwalten, nicht nur dynamische?
Ja, ueber die KV-Secrets-Engine lassen sich auch klassische, statische Werte zentral, versioniert und auditiert speichern. Die Lebensdauer des Wertes selbst muss dabei aber weiterhin manuell rotiert werden.
7Wie granular lassen sich Vault-Policies fuer GitLab-Jobs einschraenken?
Ueber Bound Claims in der JWT/OIDC-Auth-Methode laesst sich der Zugriff auf ein bestimmtes GitLab-Projekt, einen bestimmten geschuetzten Branch oder sogar einen bestimmten Job-Namen begrenzen, was deutlich feingranularer ist als eine einzelne Protected Variable.
8Was ist der Unterschied zwischen AppRole- und JWT/OIDC-Auth in Vault?
AppRole nutzt ein separat verteiltes Role-ID/Secret-ID-Paar zur Authentifizierung und eignet sich fuer Umgebungen ohne natives GitLab-JWT. JWT/OIDC nutzt dagegen direkt den von GitLab signierten ID-Token und braucht kein zusaetzlich verteiltes Geheimnis.
9Erfuellt eine Vault-Integration automatisch PCI-DSS-Anforderungen?
Nein, Vault ist ein Werkzeug, das die technische Umsetzung erleichtert, ersetzt aber nicht die organisatorischen Massnahmen und die Dokumentation, die fuer eine tatsaechliche PCI-DSS-Zertifizierung noetig sind.
10Wie starte ich die Migration von Protected Variables zu Vault am sinnvollsten?
Am besten mit dem sensibelsten einzelnen Secret beginnen, haeufig die Datenbank-Zugangsdaten fuer den Produktions-Deploy, diesen einen Job umstellen, Erfahrung sammeln und erst danach schrittweise weitere Secrets migrieren.