W3docs

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.

Nota
Una firma non cifra nulla. Il commit e il suo contenuto rimangono completamente leggibili; la firma attesta solo l'origine e l'integrità.

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 --version

Firmare 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-key

Elenca le tue chiavi e copia l'ID lungo della chiave — il valore dopo l'algoritmo sulla riga sec:

gpg --list-secret-keys --keyid-format=long
sec   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 true

Firmare 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"
Attenzione
Il caso conta: -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 true

Commit 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_signers

Caricare 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.pub come 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 tag

Per 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 fix

G 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 ~/.bashrc o ~/.zshrc). Su macOS, installa pinentry-mac affinché l'agente possa mostrare una finestra di dialogo per la password.
  • gpg: signing failed: No secret keyuser.signingkey punta a un ID errato. Ricontrolla con gpg --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 configurato gpg.ssh.allowedSignersFile (vedi sopra).

Opzioni comuni

ComandoDescrizione
git commit -SFirma un singolo commit.
git tag -s <name>Crea un tag annotato firmato.
git config commit.gpgsign trueFirma ogni commit automaticamente.
git config gpg.format sshFirma con una chiave SSH invece di GPG.
git log --show-signatureMostra 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.

Pratica

Pratica
Quali affermazioni sulla firma dei commit sono corrette?
Quali affermazioni sulla firma dei commit sono corrette?
Was this page helpful?