W3docs

Commits signieren

Lerne, Git-Commits und Tags kryptografisch mit GPG oder SSH zu signieren, um Autorschaft zu beweisen und das Verified-Badge zu erhalten.

Das Signieren eines Commits fügt eine kryptografische Signatur hinzu, die beweist, wer ihn erstellt hat und dass sein Inhalt nicht verändert wurde. Dieses Kapitel erklärt, warum Signaturen wichtig sind, wie man einen Schlüssel generiert, wie man Commits und Tags mit GPG oder SSH signiert, wie man Signaturen verifiziert und wie man die Fehler behebt, auf die man beim ersten Mal wahrscheinlich stößt.

Was das Signieren tatsächlich beweist

Standardmäßig sind der Autorenname und die E-Mail-Adresse eines Commits nur Text. Git prüft diese nie — jeder kann user.name und user.email auf beliebige Werte setzen (siehe git config) und einen Commit erstellen, der vorgibt, von jemand anderem zu stammen. Eine Signatur ändert das: Sie wird mit einem privaten Schlüssel erstellt, den nur du besitzt, und jeder mit deinem passenden öffentlichen Schlüssel kann zwei Dinge bestätigen:

  • Autorschaft — der Commit stammt wirklich vom Inhaber dieses privaten Schlüssels.
  • Integrität — wenn ein einzelnes Byte des Commits (Nachricht, Tree, Eltern-Commit, Autor) geändert wird, schlägt die Verifizierung fehl.

Für Projekte, bei denen die Herkunft wichtig ist — sicherheitskritischer Code, Open-Source-Releases, regulierte Umgebungen — ermöglicht eine signierte Historie Gutachtern zu vertrauen, wer was geschrieben hat. Auf GitHub und GitLab erhält eine verifizierte Signatur ein grünes Verified-Badge neben dem Commit.

Hinweis
Eine Signatur verschlüsselt nichts. Der Commit und sein Inhalt bleiben vollständig lesbar; die Signatur bestätigt nur Herkunft und Integrität.

GPG oder SSH wählen

Git unterstützt zwei Signaturformate. Wähle eines:

  • GPG (OpenPGP) — die traditionelle Wahl. Ausgereift, weit verbreitet, aber die Schlüsselverwaltung (Schlüsselbunde, Ablauf, der gpg-Agent) hat eine Lernkurve.
  • SSH — verfügbar seit Git 2.34. Wenn du bereits einen SSH-Schlüssel zum Pushen verwendest, kannst du ihn zum Signieren mit fast keinem zusätzlichen Aufwand wiederverwenden. Einfacher zu verwalten und für die meisten Menschen heutzutage der empfohlene Einstiegspunkt.

Prüfe zuerst deine Version:

git --version

Mit GPG signieren

Schlüssel generieren oder finden

Wenn du noch keinen GPG-Schlüssel hast, erstelle einen (übernimm die Standardwerte und wähle einen 4096-Bit-RSA- oder einen ECC-Schlüssel):

gpg --full-generate-key

Liste deine Schlüssel auf und kopiere die lange Schlüssel-ID — den Wert nach dem Algorithmus in der sec-Zeile:

gpg --list-secret-keys --keyid-format=long
sec   ed25519/3AA5C34371567BD2 2024-01-08 [SC]
      AB1C2D3E...
uid   Jane Dev <[email protected]>

Hier ist die Schlüssel-ID 3AA5C34371567BD2.

Git konfigurieren

git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true

Einen Commit oder Tag signieren

Wenn commit.gpgsign aktiviert ist, wird jeder Commit automatisch signiert. Um einen einzelnen Commit explizit zu signieren, verwende das großgeschriebene -S-Flag:

git commit -S -m "Add audited payment handler"

Um einen annotierten Tag zu signieren, verwende das kleingeschriebene -s:

git tag -s v2.0.0 -m "Signed release 2.0.0"
Warnung
Groß-/Kleinschreibung ist wichtig: -S (Großbuchstabe) signiert einen Commit, während -s (Kleinbuchstabe) einen Tag signiert. Bei git commit fügt das kleingeschriebene -s stattdessen eine Signed-off-by-Zeile hinzu — ein Klartextnachweis (Developer Certificate of Origin), keine kryptografische Signatur.

Mit SSH signieren

Wenn du einen id_ed25519-Schlüssel (oder einen anderen SSH-Schlüssel) hast, weise Git auf den öffentlichen Schlüssel hin und wechsle das Signaturformat:

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true

Commits und Tags werden nun mit denselben -S / -s-Flags wie zuvor signiert — keine weitere Änderung erforderlich.

Lokale Verifizierung für SSH aktivieren

Im Gegensatz zu GPG hat Git keinen eingebauten Vertrauensspeicher für SSH-Schlüssel, daher meldet git log --show-signature No principal matched, bis du eine Datei mit erlaubten Signierern erstellst. Ordne jeder E-Mail-Adresse ihren öffentlichen Schlüssel zu:

mkdir -p ~/.config/git
echo "[email protected] $(cat ~/.ssh/id_ed25519.pub)" >> ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers

Deinen öffentlichen Schlüssel beim Host hochladen

Das Verified-Badge erscheint erst, nachdem der Host deinen öffentlichen Schlüssel hinterlegt hat.

  • GPG: Kopiere den gepanzerten öffentlichen Schlüssel aus gpg --armor --export <key-id> und füge ihn unter Settings → SSH and GPG keys → New GPG key ein.
  • SSH: Füge den Inhalt von ~/.ssh/id_ed25519.pub als Schlüssel vom Typ Signing key (getrennt von einem Authentifizierungsschlüssel) im selben Einstellungsbereich hinzu.

Die E-Mail-Adresse auf deinem Schlüssel muss mit der Autor-E-Mail des Commits übereinstimmen, sonst zeigt der Host Unverified an.

Signaturen verifizieren

Prüfe Signaturen lokal mit einem dieser Befehle:

git log --show-signature          # show signature status in the log
git verify-commit HEAD            # verify one commit
git verify-tag v2.0.0             # verify a tag

Für eine kompakte Ansicht gibt der %G?-Platzhalter in git log einen einzelnen Statuscode pro Commit aus:

git log --pretty="%h %G? %s"
a1b2c3d G  Add audited payment handler
d4e5f6g N  Quick typo fix

G bedeutet eine gute (gültige) Signatur, B schlecht, U gut mit unbekannter Gültigkeit und N keine Signatur.

Häufige Fehler und Lösungen

  • error: gpg failed to sign the data — normalerweise kann der GPG-Agent nicht nach deiner Passphrase fragen. Exportiere das Terminal, das er verwenden soll: export GPG_TTY=$(tty) (füge es zu ~/.bashrc oder ~/.zshrc hinzu). Unter macOS installiere pinentry-mac, damit der Agent einen Passwort-Dialog öffnen kann.
  • gpg: signing failed: No secret keyuser.signingkey zeigt auf die falsche ID. Prüfe erneut mit gpg --list-secret-keys --keyid-format=long.
  • GitHub zeigt Unverified — die Autor-E-Mail des Commits stimmt nicht mit einer E-Mail überein, die mit deinem hochgeladenen Schlüssel verknüpft ist, oder der Schlüssel wurde nicht beim Host hinzugefügt.
  • No principal matched (SSH) — du hast gpg.ssh.allowedSignersFile nicht eingerichtet (siehe oben).

Häufige Optionen

BefehlBeschreibung
git commit -SSigniert einen einzelnen Commit.
git tag -s <name>Erstellt einen signierten annotierten Tag.
git config commit.gpgsign trueSigniert jeden Commit automatisch.
git config gpg.format sshMit einem SSH-Schlüssel statt GPG signieren.
git log --show-signatureZeigt den Signaturstatus im Log an.
git log --pretty="%G?"Gibt einen Signaturstatuscode pro Commit aus.
git verify-commit <commit>Verifiziert die Signatur eines Commits.
git verify-tag <tag>Verifiziert die Signatur eines Tags.

Übung

Übung
Welche Aussagen über das Signieren von Commits sind korrekt?
Welche Aussagen über das Signieren von Commits sind korrekt?
Was this page helpful?