Por que assinar commits?

Assinar commits no Git garante que o autor e o conteúdo não foram alterados desde a criação, é uma prova criptográfica ligada a uma chave privada. Sem assinatura, qualquer pessoa com acesso ao repositório (ou que consiga forjar user.name/user.email) pode criar commits que aparentam ser seus, o que dificulta auditoria e confiança no histórico.

Em repositórios pessoais, assinaturas trazem confiança no seu próprio histórico e permitem checar se um commit foi realmente gerado por você. Em ambientes profissionais, reduz-se o risco de supply-chain attacks e facilita atribuição correta de mudanças críticas.

Risco de impersonação

Se commits não são assinados, alguém pode se passar por outra pessoa simplesmente configurando localmente git config user.name "Seu Nome" e git config user.email "[email protected]". Em equipes pequenas isso pode não ser percebido até que alguém investigue o histórico, assinaturas resolvem esse problema ao ligar cada commit a uma chave gerenciável (e removível) do usuário.

Quando vale a pena?

  • projeto pessoal com histórico importante
  • repositórios públicos que você quer manter confiáveis
  • times que exigem verificação de commits
  • quando o GitHub/empresa exibe o selo Verified
  • ao migrar ou colaborar com outros desenvolvedores

Quando não é necessário?

  • experimentos rápidos e branches descartáveis
  • projetos locais sem necessidade de auditoria
  • repositórios onde a sobrecarga de configuração não compensa

SSH vs GPG: qual escolher?

Por que usar SSH?

  • mais simples quando você já usa SSH para Git
  • dispensa instalar e configurar todo o toolchain GPG
  • funciona bem em WSL, Linux, macOS e Windows
  • GitHub reconhece chaves SSH adicionadas à conta para verificação

Quando o GPG é preferível?

  • assinatura de releases/tags com garantia adicional
  • uso de hardware tokens (YubiKey/smartcard) via GPG
  • políticas corporativas que exigem GPG/Web of Trust
  • necessidade de assinar outros artefatos (e-mails, documentos)

Resumo

  • SSH: praticidade e integração direta com o fluxo de SSH/CI.
  • GPG: mais adequado quando se precisa de um modelo de confiança mais formal.

O que funcionou para mim

Uso SSH por simplicidade: já tinha chaves para GitHub, queria fluxo leve e validação rápida sem instalar ferramentas extras. Em repositórios pessoais, prefiro usar a mesma chave de conexão e assinatura para reduzir burocracia; em projetos corporativos, costumo ter chaves separadas (e-mails corporativos e políticas internas).

Passo a passo para assinar commits com SSH

1. Verifique sua versão do Git

git --version

Recomendação: Git 2.34+ (melhor suporte a gpg.format ssh e user.signingkey).

2. Decidir: mesma chave ou chave dedicada

Opções válidas:

  • Mesma chave (praticidade, uso pessoal): reaproveitar ~/.ssh/id_ed25519 ou outra chave já configurada.
  • Chave dedicada (separação de funções, mais controle): gerar ~/.ssh/id_ed25519-sign.

Exemplos:

Gerar chave dedicada:

ssh-keygen -t ed25519 -C "assinatura-git" -f ~/.ssh/id_ed25519-sign

Usar chave existente como user.signingkey:

git config --local user.signingkey ~/.ssh/id_ed25519

Observação: prefira --local quando quiser que a configuração valha apenas para um repositório.

3. Carregue a chave no agente SSH

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519-sign
# ou, se usar a mesma chave:
ssh-add ~/.ssh/id_ed25519

No Linux, considere systemctl --user enable --now ssh-agent.service ou keychain para carregar automaticamente.

4. Configure o Git para usar SSH como formato de assinatura

git config --local gpg.format ssh
git config --local user.signingkey ~/.ssh/id_ed25519-sign
git config --local commit.gpgsign true
git config --local gpg.ssh.program ssh

Use --global para aplicar a todos os repositórios ou --local para escopo por repositório.

5. Publique a chave pública no GitHub

Copie ~/.ssh/id_ed25519-sign.pub (ou id_ed25519.pub) e adicione em GitHub > Settings > SSH and GPG keys > SSH keys.

Com o CLI gh:

gh auth login
gh ssh-key add ~/.ssh/id_ed25519-sign.pub --title "assinatura-$(hostname)"

6. Configure user.name e user.email corretamente

git config --local user.name "Seu Nome"
git config --local user.email "[email protected]"

Use o e-mail vinculado à conta GitHub que contém a chave pública.

7. Commit assinado

git add .
git commit -m "Setup: assinatura SSH ativada"

Se commit.gpgsign estiver ativo, o -S será automático; senão, use -S explicitamente:

git commit -S -m "Commit assinado com SSH"

8. Commit de teste (opcional)

git commit --allow-empty -S -m "Teste de assinatura SSH"

9. Verificar assinatura localmente

git log --show-signature -1

Saída esperada: indicação de assinatura válida e o e-mail/chave usada.

10. Push e checagem no GitHub

git push origin sua-branch

No GitHub, commits assinados mostram selo Verified quando a chave pública pertence à conta.

Configuração por repositório vs global

  • --local (recomendado quando você trabalha com múltiplas contas): git config --local user.signingkey ~/.ssh/id_ed25519-corp
  • --global (bom para uso pessoal único): git config --global user.signingkey ~/.ssh/id_ed25519

Usar --local evita misturar chaves e e-mails entre contas pessoais e corporativas.

Segurança e boas práticas

  • proteja a chave privada com uma passphrase ao gerar (ssh-keygen pergunta por passphrase)
  • evite ssh-agent forwarding em hosts não confiáveis
  • restrinja permissões do arquivo (chmod 600 ~/.ssh/id_*)
  • registre e remova chaves do GitHub ao trocar dispositivos
  • considere hardware tokens (YubiKey) para maior proteção

Rotação e revogação

Se suspeitar de comprometimento:

  1. Remova a chave pública do GitHub (Settings → SSH and GPG keys).
  2. Gere uma nova chave (ssh-keygen ... -f ~/.ssh/id_ed25519-new).
  3. Adicione a nova chave ao GitHub.
  4. Atualize git config user.signingkey para a nova chave.

Ferramentas úteis

  • gh (GitHub CLI): gh ssh-key add para automatizar o upload de chaves
  • ssh-add -l para listar chaves carregadas no agent
  • ssh-keygen -lf ~/.ssh/id_ed25519.pub para ver fingerprint

Recursos e leitura adicional

  • GitHub Docs - Verificação de commits via SSH
  • Documentação do Git - gpg.format e user.signingkey

Conclusão e recomendações rápidas

  • Para uso pessoal: usar a mesma chave SSH é aceitável e muito prático.
  • Para uso profissional: prefira chaves separadas por contexto e --local onde necessário.
  • Sempre proteja a chave privada com passphrase e rotacione se houver suspeita.