Firmare i commit
Impara a firmare crittograficamente commit e tag Git con GPG o SSH per provare l'autorialità e ottenere il badge Verificato.
Firmare un commit aggiunge una firma crittografica che prova chi lo ha creato e che il suo contenuto non è stato alterato. Questo capitolo spiega perché le firme sono importanti, come generare una chiave, come firmare commit e tag con GPG o SSH, come verificare le firme e come risolvere gli errori che probabilmente incontrerai la prima volta.
Cosa prova effettivamente una firma
Per impostazione predefinita, il nome dell'autore e l'email su un commit sono semplice testo. Git non li verifica mai — chiunque può impostare user.name e user.email su qualsiasi valore (vedi git config) e produrre un commit che afferma di provenire da qualcun altro. Una firma cambia le cose: è creata con una chiave privata che solo tu possiedi, e chiunque abbia la tua chiave pubblica corrispondente può confermare due cose:
- Autorialità — il commit proviene davvero dal titolare di quella chiave privata.
- Integrità — se un singolo byte del commit (messaggio, albero, genitore, autore) cambia, la verifica fallisce.
Per i progetti in cui la provenienza è importante — codice critico per la sicurezza, release open source, ambienti regolamentati — la cronologia firmata permette ai revisori di fidarsi di chi ha scritto cosa. Su GitHub e GitLab, una firma verificata ottiene un badge verde Verified accanto al commit.
Scegliere tra GPG e SSH
Git supporta due formati di firma. Scegline uno:
- GPG (OpenPGP) — la scelta tradizionale. Maturo, ampiamente supportato, ma la gestione delle chiavi (portachiavi, scadenza, l'agente
gpg) richiede una curva di apprendimento. - SSH — disponibile da Git 2.34. Se usi già una chiave SSH per il push, puoi riutilizzarla per la firma con quasi nessuna configurazione aggiuntiva. Più semplice da gestire, ora è il punto di partenza consigliato per la maggior parte delle persone.
Controlla prima la tua versione:
git --versionFirmare con GPG
Generare o trovare una chiave
Se non hai ancora una chiave GPG, creane una (accetta le impostazioni predefinite, scegliendo RSA a 4096 bit o una chiave ECC):
gpg --full-generate-keyElenca le tue chiavi e copia l'ID lungo della chiave — il valore dopo l'algoritmo sulla riga sec:
gpg --list-secret-keys --keyid-format=longsec ed25519/3AA5C34371567BD2 2024-01-08 [SC]
AB1C2D3E...
uid Jane Dev <[email protected]>Qui l'ID della chiave è 3AA5C34371567BD2.
Configurare Git
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign trueFirmare un commit o un tag
Con commit.gpgsign attivo, ogni commit viene firmato automaticamente. Per firmare un singolo commit in modo esplicito, usa il flag -S maiuscolo:
git commit -S -m "Add audited payment handler"Per firmare un tag annotato, usa la -s minuscola:
git tag -s v2.0.0 -m "Signed release 2.0.0"-S (maiuscolo) firma un commit, mentre -s (minuscolo) firma un tag. Con git commit, la -s minuscola aggiunge invece una riga Signed-off-by — un Developer Certificate of Origin in testo normale, non una firma crittografica.Firmare con SSH
Se hai una chiave id_ed25519 (o qualsiasi chiave SSH), indica a Git la chiave pubblica e cambia il formato di firma:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign trueCommit e tag ora si firmano con gli stessi flag -S / -s di prima — non è necessario nessun altro cambiamento.
Abilitare la verifica locale per SSH
A differenza di GPG, Git non ha un archivio di fiducia integrato per le chiavi SSH, quindi git log --show-signature riporta No principal matched finché non crei un file di firmatari consentiti. Associa ogni email alla sua chiave pubblica:
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_signersCaricare la chiave pubblica sull'host
Il badge Verified appare solo dopo che l'host ha la tua chiave pubblica registrata.
- GPG: copia la chiave pubblica blindata da
gpg --armor --export <key-id>e incollala in Impostazioni → Chiavi SSH e GPG → Nuova chiave GPG. - SSH: aggiungi il contenuto di
~/.ssh/id_ed25519.pubcome chiave di tipo Signing key (separata da una chiave di autenticazione) nella stessa area delle impostazioni.
L'email sulla tua chiave deve corrispondere all'email dell'autore del commit, altrimenti l'host mostra Unverified.
Verificare le firme
Controlla le firme localmente con uno dei seguenti comandi:
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 tagPer una visualizzazione compatta, il segnaposto %G? in git log stampa un singolo codice di stato per commit:
git log --pretty="%h %G? %s"a1b2c3d G Add audited payment handler
d4e5f6g N Quick typo fixG indica una firma valida (buona), B cattiva, U buona ma con validità sconosciuta, e N nessuna firma.
Errori comuni e soluzioni
error: gpg failed to sign the data— di solito l'agente GPG non riesce a richiedere la passphrase. Esporta il terminale che deve usare:export GPG_TTY=$(tty)(aggiungilo a~/.bashrco~/.zshrc). Su macOS, installapinentry-macaffinché l'agente possa mostrare una finestra di dialogo per la password.gpg: signing failed: No secret key—user.signingkeypunta a un ID errato. Ricontrolla congpg --list-secret-keys --keyid-format=long.- GitHub mostra Unverified — l'email dell'autore del commit non corrisponde a un'email associata alla chiave caricata, oppure la chiave non è stata aggiunta all'host.
No principal matched(SSH) — non hai configuratogpg.ssh.allowedSignersFile(vedi sopra).
Opzioni comuni
| Comando | Descrizione |
|---|---|
git commit -S | Firma un singolo commit. |
git tag -s <name> | Crea un tag annotato firmato. |
git config commit.gpgsign true | Firma ogni commit automaticamente. |
git config gpg.format ssh | Firma con una chiave SSH invece di GPG. |
git log --show-signature | Mostra lo stato della firma nel log. |
git log --pretty="%G?" | Stampa un codice di stato firma per ogni commit. |
git verify-commit <commit> | Verifica la firma di un commit. |
git verify-tag <tag> | Verifica la firma di un tag. |