Foto: Luca Bravo / Unsplash
Wie entferne ich Passwörter und API-Schlüssel aus dem Git-Verlauf?
Zuerst den Schlüssel sperren und neu erzeugen – das ist der wichtigste Schritt, denn Kopien existieren womöglich längst. Danach den Verlauf mit git filter-repo bereinigen, neu hochladen, alle alten Kopien einsammeln und dafür sorgen, dass es nicht wieder passiert.
Warum Löschen allein nicht reicht
Ein neuer Commit, der den Schlüssel entfernt, ändert nichts an der Vergangenheit: Im Verlauf steht er weiter, und jeder, der das Repository klont, kann ihn finden.
- Öffentliche Repositories werden automatisiert nach Schlüsseln durchsucht – oft innerhalb von Minuten nach dem Push.
- Klone, Forks, CI-Caches und Backups enthalten den Schlüssel weiterhin.
Deshalb gilt: Ein Schlüssel, der einmal im Verlauf war, ist verbrannt. Das Bereinigen des Verlaufs ist Aufräumen, nicht Rettung.
Schritt 1: Schlüssel sperren und neu erzeugen
- Widerruft den Schlüssel beim Anbieter – OpenAI, Stripe, AWS, Supabase oder wer auch immer ihn ausgestellt hat – und erzeugt einen neuen.
- Hinterlegt den neuen Schlüssel als Umgebungsvariable beim Hoster oder in der CI, nicht im Code.
- Prüft Logs und Abrechnungen des Anbieters: Wurde der alte Schlüssel von Fremden benutzt?
Schritt 2: Herausfinden, was noch im Verlauf steckt
Selten ist es nur ein Schlüssel. Das Werkzeug gitleaks durchsucht den kompletten Verlauf:
gitleaks git -v
Ältere Versionen nutzen dafür gitleaks detect. Jeder Treffer kommt auf die Liste: sperren, neu erzeugen, später aus dem Verlauf entfernen.
Schritt 3: Den Verlauf bereinigen
Das empfohlene Werkzeug ist git filter-repo. Es schreibt den Verlauf neu – also vorher sichern:
git clone --mirror git@github.com:firma/app.git app-sicherung.git
Dann in einem frischen Klon arbeiten. Eine Datei wie .env komplett aus dem Verlauf entfernen:
git filter-repo --invert-paths --path .env
Einzelne Schlüssel überall ersetzen – in einer Textdatei steht pro Zeile, was wodurch ersetzt wird:
echo 'MEIN-GEHEIMER-SCHLUESSEL==>ENTFERNT' > ersetzen.txt
git filter-repo --replace-text ersetzen.txt
git filter-repo entfernt danach absichtlich die Verbindung zum Server. Also neu verbinden und den bereinigten Stand hochladen:
git remote add origin git@github.com:firma/app.git
git push --force --all
git push --force --tags
Ist der Hauptzweig gegen Force-Push geschützt, muss der Schutz dafür kurz aufgehoben werden. Eine Alternative zu filter-repo ist der BFG Repo-Cleaner.
Schritt 4: Alle alten Kopien einsammeln
- Alle im Team löschen ihre alten Klone und klonen neu. Sonst bringt der nächste Push den alten Verlauf zurück.
- Bei GitHub können Verweise in Pull Requests und zwischengespeicherte Ansichten bestehen bleiben. Diese entfernt nur der GitHub-Support.
- Leert Caches und Artefakte der CI.
Schritt 5: Dafür sorgen, dass es nicht wieder passiert
- Tragt
.envund ähnliche Dateien in die.gitignoreein und legt eine.env.exampleohne echte Werte ins Repository. - Ein Pre-Commit-Hook mit gitleaks stoppt Commits mit Schlüsseln, bevor sie entstehen.
- Aktiviert Secret Scanning und Push Protection bei GitHub oder GitLab, soweit euer Tarif es anbietet.
- Nehmt den Secret-Scan in eure automatische Prüfstrecke auf – siehe Was ist CI/CD und warum brauche ich das beim Vibe Coding?
- Haltet in den Regeln für eure KI-Assistenten fest, dass Schlüssel nur über Umgebungsvariablen eingebunden werden.
Unsicher, ob in eurem Repository noch etwas schlummert? Der Betriebscheck durchsucht Code und Verlauf nach Schlüsseln und zeigt, was zu tun ist.