Firmar commits
Aprende a firmar criptográficamente commits y etiquetas de Git con GPG o SSH para demostrar autoría y obtener la insignia Verificado.
Firmar un commit adjunta una firma criptográfica que demuestra quién lo creó y que su contenido no ha sido alterado. Este capítulo explica por qué importan las firmas, cómo generar una clave, cómo firmar commits y etiquetas con GPG o SSH, cómo verificar firmas y cómo corregir los errores que probablemente encuentres la primera vez.
Qué prueba realmente una firma
De forma predeterminada, el nombre del autor y el correo electrónico en un commit son solo texto. Git nunca los verifica: cualquiera puede establecer user.name y user.email en cualquier valor (consulta git config) y producir un commit que afirme ser de otra persona. Una firma cambia eso: se realiza con una clave privada que solo tú posees, y cualquier persona con tu clave pública correspondiente puede confirmar dos cosas:
- Autoría — el commit realmente provino del titular de esa clave privada.
- Integridad — si cambia un solo byte del commit (mensaje, árbol, padre, autor), la verificación falla.
Para proyectos donde la procedencia importa — código sensible a la seguridad, lanzamientos de código abierto, entornos regulados — el historial firmado permite a los revisores confiar en quién escribió qué. En GitHub y GitLab, una firma verificada obtiene una insignia verde Verificado junto al commit.
Elegir entre GPG o SSH
Git admite dos formatos de firma. Elige uno:
- GPG (OpenPGP) — la opción tradicional. Maduro, ampliamente compatible, pero la gestión de claves (llaveros, caducidad, el agente
gpg) tiene una curva de aprendizaje. - SSH — disponible desde Git 2.34. Si ya usas una clave SSH para hacer push, puedes reutilizarla para firmar con casi ninguna configuración adicional. Más sencillo de gestionar, ahora es el punto de partida recomendado para la mayoría.
Verifica tu versión primero:
git --versionFirmar con GPG
Generar o encontrar una clave
Si aún no tienes una clave GPG, crea una (acepta los valores predeterminados, eligiendo RSA de 4096 bits o una clave ECC):
gpg --full-generate-keyLista tus claves y copia el ID de clave largo — el valor después del algoritmo en la línea sec:
gpg --list-secret-keys --keyid-format=longsec ed25519/3AA5C34371567BD2 2024-01-08 [SC]
AB1C2D3E...
uid Jane Dev <[email protected]>Aquí el ID de clave es 3AA5C34371567BD2.
Configurar Git
git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign trueFirmar un commit o etiqueta
Con commit.gpgsign activado, cada commit se firma automáticamente. Para firmar un único commit de forma explícita, usa la bandera -S en mayúscula:
git commit -S -m "Add audited payment handler"Para firmar una etiqueta anotada, usa la -s en minúscula:
git tag -s v2.0.0 -m "Signed release 2.0.0"-S (mayúscula) firma un commit, mientras que -s (minúscula) firma una etiqueta. En git commit, la -s minúscula añade en cambio una línea Signed-off-by — un Certificado de Origen del Desarrollador en texto plano, no una firma criptográfica.Firmar con SSH
Si tienes una clave id_ed25519 (o cualquier clave SSH), apunta Git a la clave pública y cambia el formato de firma:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign trueLos commits y etiquetas ahora se firman con las mismas banderas -S / -s que antes — no se necesita ningún otro cambio.
Habilitar la verificación local para SSH
A diferencia de GPG, Git no tiene un almacén de confianza integrado para claves SSH, por lo que git log --show-signature reporta No principal matched hasta que crees un archivo de firmantes permitidos. Asigna cada correo electrónico a su clave pública:
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_signersSubir tu clave pública al servidor
La insignia Verificado solo aparece después de que el servidor tiene tu clave pública registrada.
- GPG: copia la clave pública en formato blindado desde
gpg --armor --export <key-id>y pégala en Configuración → Claves SSH y GPG → Nueva clave GPG. - SSH: añade el contenido de
~/.ssh/id_ed25519.pubcomo clave de tipo Clave de firma (separada de una clave de autenticación) en la misma área de configuración.
El correo electrónico de tu clave debe coincidir con el correo del autor del commit, o el servidor mostrará No verificado.
Verificar firmas
Comprueba las firmas localmente con cualquiera de estos comandos:
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 tagPara una vista compacta, el marcador %G? en git log imprime un código de estado por commit:
git log --pretty="%h %G? %s"a1b2c3d G Add audited payment handler
d4e5f6g N Quick typo fixG significa firma válida (buena), B mala, U buena con validez desconocida, y N sin firma.
Errores comunes y soluciones
error: gpg failed to sign the data— generalmente el agente GPG no puede solicitar tu contraseña. Exporta la terminal que debe usar:export GPG_TTY=$(tty)(agrégalo a~/.bashrco~/.zshrc). En macOS, instalapinentry-macpara que el agente pueda mostrar un diálogo de contraseña.gpg: signing failed: No secret key—user.signingkeyapunta al ID incorrecto. Vuelve a verificar congpg --list-secret-keys --keyid-format=long.- GitHub muestra Unverified — el correo electrónico del autor del commit no coincide con un correo adjunto a tu clave subida, o la clave no fue añadida al servidor.
No principal matched(SSH) — no has configuradogpg.ssh.allowedSignersFile(ver arriba).
Opciones comunes
| Comando | Descripción |
|---|---|
git commit -S | Firma un único commit. |
git tag -s <name> | Crea una etiqueta anotada firmada. |
git config commit.gpgsign true | Firma cada commit automáticamente. |
git config gpg.format ssh | Firmar con una clave SSH en lugar de GPG. |
git log --show-signature | Muestra el estado de la firma en el registro. |
git log --pretty="%G?" | Imprime un código de estado de firma por commit. |
git verify-commit <commit> | Verifica la firma de un commit. |
git verify-tag <tag> | Verifica la firma de una etiqueta. |