Zum Hauptinhalt springen

Repositorys mit Secrets in der Historie migrieren

fremforge führt bei jedem Push einen gitleaks-Pre-Receive-Hook aus, auch beim ersten Mirror-Push, der die Historie eines Kunden in eine fremforge-Organisation bringt. Enthält das Quell-Repository in irgendeinem Commit der Historie Secrets (eine alte .env, einen geleakten API-Schlüssel, einen privaten SSL-Schlüssel usw.), schlägt der Import-Push fehl und die Migration kommt zum Stillstand.

Diese Seite beschreibt die beiden unterstützten Optionen. Option A ist für die meisten Teams der empfohlene Weg; Option B ist ein letzter Ausweg.

Option A: das Secret rotieren und die Historie umschreiben (empfohlen)

Am besten geeignet, wenn:

  • Das geleakte Secret ein echtes ist (API-Schlüssel, privater SSH-Schlüssel, Zertifikat, Passwort). Es muss ohnehin ungültig gemacht werden, egal wo das Repository liegt; bleibt es in der Git-Historie irgendeines Hosts, ist es dauerhaft offengelegt.
  • Das Team etwa eine Stunde für das Umschreiben der Historie und den Force-Push zur Quelle aufwenden kann.

Vorgehen:

  1. Rotiere zuerst das geleakte Secret. Bevor du Git anfasst: Ändere den API-Schlüssel, widerrufe den SSH-Schlüssel, tausche das Zertifikat aus. Der geleakte Wert sollte ungültig sein, bevor die Historie umgeschrieben wird; dann ist er harmlos, selbst wenn das Umschreiben unvollständig bleibt.
  2. Ermittle den oder die Commits. Die gitleaks-Ausgabe des Importversuchs bei fremforge nennt die Regel und den Commit-SHA. Stell sicher, dass du verstehst, um welches Secret und welche Commits es geht.
  3. Schreibe die Historie mit git filter-repo um. (Upstream-Dokumentation)
    # Install: brew install git-filter-repo  (or pip install git-filter-repo)
    # Verify upstream is clean:
    git clone --mirror <source-url> repo.git
    cd repo.git
    # Replace the secret value across history (string-replace shape):
    echo 'literal:AKIAEXAMPLE12345===>REDACTED' > replace.txt
    git filter-repo --replace-text replace.txt
    # OR: drop the file containing the secret across history:
    git filter-repo --invert-paths --path path/to/leaky/file
  4. Force-pushe die umgeschriebene Historie zuerst ins Quell-Repository.
    • Erst das Umschreiben auf der Quellseite macht die Behebung dauerhaft. Pushst du die umgeschriebene Historie nur zu fremforge, hat jemand, der die Quelle vor dem Umschreiben geklont hat, den geleakten Wert weiterhin.
    • GitHub: git push --force-with-lease --mirror
    • GitLab und ADO: ebenso. Beide lehnen Force-Pushes auf geschützte Branches standardmäßig ab; lockere den Schutz vorübergehend, pushe und schütze den Branch danach wieder.
  5. Führe die Migration nach dem normalen Verfahren durch, siehe GitHub / GitLab / Azure DevOps.
  6. Prüfe nach dem Import, dass das gitleaks-Log von fremforge für den Migrations-Push keine Blockierungen zeigt.

Einschränkungen:

  • Forks und Klone enthalten weiterhin die ursprüngliche Historie. Es gibt keinen Weg, jeden Klon zurückzuholen; deshalb ist Schritt 1 (zuerst das Secret rotieren) der entscheidende Schritt.
  • Das Umschreiben der Historie bricht jeden offenen PR/MR und jeden Branch in der Quelle. Stimm dich mit dem Team ab, bevor du Enter drückst; manche Hosts schließen PRs nach einem Rebase sauber, andere zeigen sie als „in N+1 Commits gemergt“ an.
  • Die Integrität von Tags und Signaturen geht verloren: Jeder signierte Tag, der auf einen umgeschriebenen Commit zeigt, ist nicht mehr gültig. Setze die Tags nach dem Umschreiben neu.

Option B: mit einem leeren Repository beginnen und nur den neuesten Commit pushen (letzter Ausweg)

Am besten geeignet, wenn:

  • Die Historie der Quelle zu verworren ist, um sie sauber umzuschreiben.
  • Das Team bereit ist, auf die gesamte Blame- und Log-Historie zu verzichten; nur der aktuelle Stand zählt.
  • Häufig bei archivierten Projekten, die „zur Aufbewahrung“ gespiegelt werden, aber nicht aktiv weiterentwickelt werden.

Vorgehen:

  1. Klone den neuesten Stand des Quell-Repositorys (beliebiger Branch) in ein Arbeitsverzeichnis.
  2. rm -rf .git && git init && git add . && git commit -m "Initial import: <source-url>@<commit-sha>".
  3. Pushe das neue Repository mit seinem einzigen Commit nach dem normalen Verfahren zu fremforge.
  4. Füge eine NOTES.md oder einen Link im CHANGELOG hinzu, der für alle im Team, die die vollständige Historie brauchen, auf die Quelle zurückverweist.

Was dabei verloren geht:

  • Die gesamte Historie von git blame / git log.
  • Alle Diffs historischer PRs / MRs (die bleiben beim Quell-Host, bis du ihn löschst).
  • Alle Signaturen historischer Commits.

Zwischen den beiden wählen

FrageOption AOption B
Ist das Secret noch gültig?zuerst rotierenentfällt
Muss die Historie erhalten bleiben?umgeschriebenverworfen
Einmaliger Push?jaja
Geht die Arbeit im selben Repository weiter?jaja
Sind Forks/Klone mit dem Leak noch im Umlauf?Restrisiko nur, wenn nicht rotiertentfällt (Historie nicht in fremforge)
Ist ein Eingriff des Betreibers nötig?neinnein

Nimm standardmäßig Option A, sofern nicht ein gewichtiger Grund dagegen spricht.

Verwandte Themen