Confirmación de cambios firmados en Git¶
Cualquiera puede configurar un nombre y correo en Git y hacer un commit que aparente ser de otra persona. Esto es un riesgo cuando importa la trazabilidad de la identidad, especialmente en:
- Proyectos de código abierto con muchos colaboradores.
- Repositorios donde las contribuciones cuentan para una certificación legal o compliance.
- Equipos que necesitan probar quién introdujo un cambio.
Git resuelve esto con firmas criptográficas: cada commit puede venir con una prueba matemática de que fue generado por la persona que dice ser. GitHub (y GitLab) validan esa firma y muestran el badge "Verified" al lado del commit.
flowchart LR
Dev[Tu PC] -->|git commit -S| Commit[Commit firmado]
Commit -->|hash + firma| GitHub
GitHub -->|verifica firma con tu llave pública| Badge[Badge 'Verified']
1. Elegir una herramienta de firma¶
Hay dos formas modernas de firmar commits:
| Herramienta | Algoritmo | Soporte | Notas |
|---|---|---|---|
| GnuPG (GPG) | RSA, Ed25519, ECC | GitHub, GitLab, Bitbucket, Gitea | Estándar clásico. Requiere instalar GPG. |
| SSH signing | Ed25519, RSA | GitHub (desde 2022), GitLab | Reusa tu llave SSH existente. Más simple. |
En esta guía usamos GPG porque es el método más universal. Si ya tenés SSH configurado, podés ver la guía oficial de GitHub sobre SSH signing como alternativa.
2. Instalar GnuPG¶
- Descargá Gpg4Win.
- En el instalador, solo tildá "GnuPG" (las demás herramientas son opcionales y suman ruido al menú).
- Después de instalar, abrí Git Bash y verificá:
3. Generar la llave GPG¶
Generá una llave nueva con el algoritmo Ed25519 (recomendado) o RSA 4096 (compatibilidad amplia):
El 0 final significa que la llave no expira. Si querés que
expire, reemplazalo por una duración como 1y (un año) o 2y.
Después de unos segundos, GPG te confirma con un mensaje similar a:
gpg: key 5F2A8B3C9D4E1F6A marked as ultimately trusted
gpg: revocation certificate stored as '/home/usuario/.gnupg/openpgp-revocs.d/5F2A8B3C9D4E1F6A.rev'
Guardá el certificado de revocación
El archivo .rev sirve para revocar la llave si se ve
comprometida. Guardalo en un lugar seguro (no en el mismo
equipo).
4. Obtener el ID de la llave¶
Para que Git y GitHub identifiquen tu llave, necesitás el ID largo:
Vas a ver algo como:
sec ed25519/5F2A8B3C9D4E1F6A 2026-01-15 [SC]
1234567890ABCDEF1234567890ABCDEF12345678
uid [ultimate] Tu Nombre <tu.correo@ejemplo.com>
ssb ed25519/A1B2C3D4E5F6G7H8 2026-01-15 [E]
El ID que necesitás es el que aparece después de ed25519/ en la
línea sec: en este caso, 5F2A8B3C9D4E1F6A.
5. Exportar la llave pública en formato ASCII¶
Para subirla a GitHub:
Copiá todo el output, incluyendo las líneas:
El comando armor
Sin --armor, GPG exporta la llave en binario. GitHub necesita
el formato ASCII (base64) para pegarlo en un formulario web.
6. Subir la llave a GitHub¶
- Andá a github.com/settings/gpg/new.
- Title: un nombre descriptivo (ej. "GPG MacBook personal").
- Key: pegá el bloque que copiaste.
- Clic en Add GPG key.
Si el correo de la llave coincide con un correo verificado de tu cuenta de GitHub, los commits firmados con esa llave van a mostrarse como Verified.
Múltiples correos
Si usás varios correos (trabajo + personal), agregá cada uno a
la llave al momento de generarla, o generá llaves separadas y
subí cada una. Para que un commit firmado se muestre como
verificado, el user.email de Git tiene que coincidir con un
correo de la llave Y estar verificado en GitHub.
7. Configurar Git para usar la llave¶
Indicá a Git qué llave usar para firmar:
git config --global user.signingkey 5F2A8B3C9D4E1F6A
git config --global commit.gpgsign true # firmar TODOS los commits
git config --global tag.gpgsign true # firmar los tags también
Con commit.gpgsign true, no necesitás acordarte de tipear -S en
cada commit; Git firma automáticamente.
Si gpg no está en tu PATH
En Windows con Git Bash, GPG se instala en
C:\Program Files (x86)\GnuPG\bin\gpg.exe. Si Git no lo
encuentra, configurá la ruta manualmente:
8. Hacer commits firmados¶
Si activaste commit.gpgsign true, todos tus commits quedan
firmados automáticamente. Si lo desactivaste:
Para merges:
--verify-signatures rechaza el merge si alguno de los commits
entrantes no está firmado. Útil cuando el repositorio exige
firma obligatoria (lo verás en las branch protection rules).
9. Verificar firmas localmente¶
Para inspeccionar la firma de un commit:
Vas a ver:
commit 8a4f9c2b3e1d7a6f...
gpg: Signature made [date]
gpg: using EDDSA key 5F2A8B3C9D4E1F6A
gpg: Good signature from "Tu Nombre <tu.correo@ejemplo.com>"
Si la firma es inválida, GPG muestra BAD signature. En ese caso,
no confíes en el commit: podría haber sido manipulado.
10. Rotar una llave comprometida¶
Si tu llave privada se ve expuesta (laptop robada, backup filtrado), revocá la llave inmediatamente:
- Importá el certificado de revocación:
- Publicá la revocación en un servidor de llaves público:
-
Quitá la llave de GitHub (Settings → SSH and GPG keys).
-
Generá una llave nueva y repetí el proceso de upload.
Caducidad preventiva
Una alternativa al certificado de revocación es generar llaves con expiración (ej. 1 año) y renovarlas antes de que expiren. Es disciplina, pero reduce la ventana de exposición.
11. Almacenar credenciales GPG (caché de passphrase)¶
Cada vez que firmás un commit, GPG te pide la passphrase para
desbloquear la llave privada. Si tuvieras que tipearla en cada commit,
el flujo se vuelve tedioso. La solución es gpg-agent, un proceso en
segundo plano (análogo a ssh-agent) que cachea la passphrase
desbloqueada por un tiempo configurable.
Configurar el TTL del caché¶
El TTL por defecto suele ser 10 horas (3600 segundos × 10) tras
la última vez que usaste la llave. Para modificarlo, editá
~/.gnupg/gpg-agent.conf:
Después de editar, recargá el agente:
Pinentry: la ventana que pide la passphrase¶
gpg-agent delega la captura de la passphrase a un programa llamado
pinentry. El comportamiento cambia según el sistema:
Por defecto usa pinentry-tty (lee la passphrase desde la
terminal). Si preferís una GUI, instalá pinentry-gnome3 (GNOME)
o pinentry-qt (KDE) y elegilo en gpg-agent.conf:
GPG Suite instala pinentry-mac, una
ventanita nativa con la opción "Save in Keychain" para no
volver a pedir la passphrase hasta el TTL configurado.
Gpg4win trae pinentry-qt o pinentry-w32 (elegible desde
gpg-agent.conf). La passphrase queda cacheada por gpg-agent
hasta el TTL configurado.
GPG-agent no es lo mismo que Git Credential Manager
gpg-agent cachea la passphrase de tu llave GPG para firmar
commits. No cachea credenciales HTTPS. Para autenticarte vía
HTTPS usá Git Credential
Manager
(GCM), que cubre usuario y token pero no firma commits. Son
dos sistemas independientes.
Si VS Code no encuentra gpg
En Windows con Git Bash, GPG se instala en
C:\Program Files (x86)\GnuPG\bin\gpg.exe. Si al firmar un
commit desde VS Code ves gpg: failed to start..., declarale la
ruta manualmente:
Próximo paso¶
Con la firma criptográfica cubierta, podés volver a Fundamentos de Git y GitHub para repasar el flujo de Pull Requests, o saltar a la sección de Práctica para hacer ejercicios completos.