Chapters ▾ 2nd Edition

7.4 Ferramentas do Git - Assinando Seu Trabalho

Assinando Seu Trabalho

O Git é criptograficamente seguro, mas não é infalível. Se você está pegando o trabalho de outras pessoas na internet e quer verificar se os commits são realmente de uma fonte confiável, o Git tem algumas maneiras de assinar e verificar o trabalho usando GPG.

Introdução ao GPG

Em primeiro lugar, se você quiser assinar alguma coisa, você precisa configurar o GPG e ter a sua chave pessoal instalada.

$ gpg --list-keys
/Users/schacon/.gnupg/pubring.gpg
---------------------------------
pub   2048R/0A46826A 2014-06-04
uid                  Scott Chacon (Git signing key) <schacon@gmail.com>
sub   2048R/874529A9 2014-06-04

Se você não tem uma chave instalada, você pode gerar uma com gpg --gen-key.

$ gpg --gen-key

Depois que você tiver uma chave privada para assinar, você pode configurar o Git para usá-la para assinar coisas, definindo a configuração user.signingkey.

$ git config --global user.signingkey 0A46826A!

Agora o Git usará a sua chave por padrão para assinar tags e commits, se você quiser.

Assinando Tags

Se você tem uma chave privada GPG configurada, você pode agora usá-la para assinar novas tags. Tudo o que você tem a fazer é usar -s em vez de -a:

$ git tag -s v1.5 -m 'my signed 1.5 tag'

You need a passphrase to unlock the secret key for
user: "Ben Straub <ben@straub.cc>"
2048-bit RSA key, ID 800430EB, created 2014-05-04

Se você executar git show nessa tag, poderá ver sua assinatura GPG anexada a ela:

$ git show v1.5
tag v1.5
Tagger: Ben Straub <ben@straub.cc>
Date:   Sat May 3 20:29:41 2014 -0700

my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
=EFTF
-----END PGP SIGNATURE-----

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

Verificando Tags

Para verificar uma tag assinada, você usa git tag -v <nome-da-tag>. Este comando usa o GPG para verificar a assinatura. Você precisa da chave pública de quem assinou em seu chaveiro (keyring) para que isso funcione corretamente:

$ git tag -v v1.4.2.1
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
type commit
tag v1.4.2.1
tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700

GIT 1.4.2.1

Minor fixes since 1.4.2, including git-mv and git-http with alternates.
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
gpg:                 aka "[jpeg image of size 1513]"
Primary key fingerprint: 3565 2A26 2040 E066 C9A7  4A7D C0C6 D9A4 F311 9B9A

Se você não tiver a chave pública de quem assinou, obterá algo assim em vez disso:

gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Can't check signature: public key not found
error: could not verify the tag 'v1.4.2.1'

Assinando Commits

Nas versões mais recentes do Git (v1.7.9 e superior), agora você também pode assinar commits individuais. Se você estiver interessado em assinar commits diretamente em vez de apenas as tags, tudo o que você precisa fazer é adicionar um -S ao seu comando git commit.

$ git commit -a -S -m 'Signed commit'

You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
2048-bit RSA key, ID 0A46826A, created 2014-06-04

[master 5c3386c] Signed commit
 4 files changed, 4 insertions(+), 24 deletions(-)
 rewrite Rakefile (100%)
 create mode 100644 lib/git.rb

Para ver e verificar essas assinaturas, há também a opção --show-signature para o git log.

$ git log --show-signature -1
commit 5c3386cf54bba0a33a32da706aa52bc0155503c2
gpg: Signature made Wed Jun  4 19:49:17 2014 PDT using RSA key ID 0A46826A
gpg: Good signature from "Scott Chacon (Git signing key) <schacon@gmail.com>"
Author: Scott Chacon <schacon@gmail.com>
Date:   Wed Jun 4 19:49:17 2014 -0700

    Signed commit

Além disso, você pode configurar o git log para verificar quaisquer assinaturas que ele encontre e listá-las em sua saída com o formato %G?.

$ git log --pretty="format:%h %G? %aN  %s"

5c3386c G Scott Chacon  Signed commit
ca82a6d N Scott Chacon  Change the version number
085bb3b N Scott Chacon  Remove unnecessary test code
a11bef0 N Scott Chacon  Initial commit

Aqui podemos ver que apenas o commit mais recente é assinado e válido, e os commits anteriores não são.

No Git 1.8.3 e versões posteriores, você pode dizer ao git merge e git pull para inspecionarem e rejeitarem a mesclagem de um commit que não carrega uma assinatura GPG confiável com o comando --verify-signatures.

Se você usar essa opção ao mesclar (fazer merge de) um branch e ele contiver commits que não estão assinados e válidos, a mesclagem não funcionará.

$ git merge --verify-signatures non-verify
fatal: Commit ab06180 does not have a GPG signature.

Se a mesclagem contiver apenas commits assinados válidos, o comando de merge mostrará a você todas as assinaturas que verificou e então prosseguirá com a mesclagem.

$ git merge --verify-signatures signed-branch
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>
Updating 5c3386c..13ad65e
Fast-forward
 README | 2 ++
 1 file changed, 2 insertions(+)

Você também pode usar a opção -S com o comando git merge para assinar o próprio commit de merge resultante. O exemplo a seguir verifica se todo commit no branch a ser mesclado está assinado e, além disso, assina o commit de merge resultante.

$ git merge --verify-signatures -S  signed-branch
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>

You need a passphrase to unlock the secret key for
user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
2048-bit RSA key, ID 0A46826A, created 2014-06-04

Merge made by the 'recursive' strategy.
 README | 2 ++
 1 file changed, 2 insertions(+)

Todos Devem Assinar

Assinar tags e commits é ótimo, mas se você decidir usar isso em seu fluxo de trabalho normal, terá que se certificar de que todos em sua equipe entendam como fazê-lo. Isso pode ser alcançado pedindo a todos que trabalham com o repositório para rodar git config --local commit.gpgsign true para que todos os seus commits no repositório sejam automaticamente assinados por padrão. Se você não o fizer, acabará passando muito tempo ajudando as pessoas a descobrir como reescrever seus commits com versões assinadas. Certifique-se de que você entende o GPG e os benefícios de assinar as coisas antes de adotar isso como parte de seu fluxo de trabalho padrão.