Comment signer ses commits sur Github
Tags: github, french
Published: 2020-09-21 08:07:07

Qui se souvient de son époque au collège, au lycée ou à la fac, l'époque des contrôles continus et des exams? De ces tas de copies rendues sur lesquelles seul le nom en tête de page pouvait vous identifier?

Eh bien, lorsqu'on "commit" c'est la même chose!
On peut commit avec notre propre compte Github mais aussi en utilisant les infos d'un autre utilisateur.

Pour cela il suffit de récupérer les infos d'un autre compte, par exemple, en clonant un des "repos" du compte en question et de faire un simple:

> git log

Puis de modifier vos infos, avant le commit, avec celles récupérées ainsi:

> git config user.name 'xxx'
> git config user.email 'xxx.yyy@mail.com'

Et voila, vous pouvez maintenant commit une modification sous le nom d'un tiers.

Les détails liés à la personne d'origine du commit n'a pas pour but de servir de moyen d'authentification.

En usurpant le nom d'un compte pour commit, il n'y a pas de faille de sécurité. Ce changement ne permet pas de commit sur les repos du dit compte. Github demanderait alors de s'authentifier avec ses logs avant de pouvoir faire le moindre "push".

Il vous est donné la possibilité de rajouter un niveau supérieur de certification, pour cela apprenons à signer nos commits !


## 1 - Préparer le terrain

Avant tout, vous aurez besoin, dans un premier temps et si ce n'est pas déjà fait, d'installer GPG :

**Pour mac :**

Lancez la commande :

> brew install gpg

Créez ou ajoutez à votre fichier ~/.gnupg/gpg.conf :

```
# Enable gpg to use the gpg-agent
use-agent
```

Pour vous éviter de réécrire votre phrase secrète trop souvent (cette phrase arrive dans la partie "les clefs GPG") installez pinentry-mac :

> brew install pinentry-mac

Et, créez ou ajoutez à votre fichier ~/.gnupg/gpg-agent.conf :

```
# cache your passphrase in your mac keychain
pinentry-program /usr/local/bin/pinentry-mac
```

Modifiez votre ~/.bashrc, ~/.zprofile... en y ajoutant les lignes suivantes :

```
export GPG_TTY=$(tty)
gpgconf --launch gpg-agent
```

Il sera parfois nécessaire de redémarrer votre agent GPG :

> gpgconf --kill gpg-agent

> gpgconf --launch gpg-agent

Vous pouvez vérifier si tout marche bien :

> echo "test" | gpg --clearsign

Vous devrez alors voir apparaitre le prompt suivant, n'oubliez de cocher la case _save in_ keychain.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tekrvq5uxeje2aocq9ua.png)

**Pour les pc sous windows :**

Allez directement sur [le site de GnuPG](https://gnupg.org/download/) et téléchargez la dernière version de GnuPG.

## 2 - Les clefs GPG

Maintenant que les préparatifs sont finis, la 2ième étape consiste à créer la paire de clefs GPG, une publique et une privée, qui vous serviront à vous identifier à l'avenir. Pour les générer, commencez avec la commande :

> gpg --full-gen-key

Une fois lancée, plusieurs questions vous serons posées :

1. Le type de clef désiré, j'ai personnellement opté pour une clef RSA.
2. La taille des clefs.
3. La duré de validité.
4. Vos informations.
5. La phrase pour chiffrer la clef secrète sur votre disque dur. **Attention** ne perdez pas cette phrase !

Vous pouvez ainsi générer autant de paires que nécessaire. Il vous faut maintenant déterminer laquelle de ces paires vous utiliserez. Pour lister vos clefs :

> gpg --list-secret-keys --keyid-format LONG

```
/Users/max/.gnupg/pubring.kbx
-----------------------------
sec   rsa4096/XXXXXXXXXXXXXXX 2020-09-17 [SC] [expire : 2021-09-17]
      YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
uid        [  ultime ] user (commentaire) <user@mail.com>

```

Dans l'exemple ci-dessus la série de chiffre **XXXXXXXXXXXXXXX** représente l'identification d'une clef privée, son ID.

## 3 - Configurer le compte Github

Après avoir généré une paire de clef GPG passez à la configuration de Github. Il vous faut, pour cela, votre clef GPG publique trouvable grâce à l'ID vu précédemment :

> gpg --armor --export XXXXXXXXXXXXXXX

```
-----BEGIN PGP PUBLIC KEY BLOCK-----

.
.
.

-----END PGP PUBLIC KEY BLOCK-----
```

Il ne vous reste plus qu'à [ajouter votre clef publique](https://github.com/settings/keys) dans les paramètres de votre compte Github.

## 4 - Se simplifier la tâche

Et c'est à peu près fini. A partir de maintenant vous allez pouvoir signer l'ensemble de vos commit en rajoutant l'option -S suivie de l'ID de votre clef secrète. Cela marche aussi pour les tag. Pas bien compliqué non ?

> git commit -S XXXXXXXXXXXXXXX

Bon, rien que de penser à tapper ces nouvelles infos à chaque commit j'en ai des vertiges. Heureusement, on peut aller plus loin dans notre démarche.

Pour ce faire, il faut **éditer le ~/.gitdonfig** :

> git config --global user.signingkey XXXXXXXXXXXXXXX

Voila ! Plus besoin d'inscrire l'ID a chaque commit. Un simple git commit -S suffira.

Si vous avez dans l'idée de signer l'intégralité de vos commits et d'en finir avec le -S il suffit de le spécifier sur votre gitconfig :

> git config --global commit.gpgSign true

> git config --global tag.gpgSign true

Votre fichier ~/.gitconfig devrait ressembler à ça maintenant:

```
[user]
  name = user
  email = mail
  signingkey = XXXXXXXXXXXXXXX
[commit]
  gpgsign = true
[tag]
  gpgsign = true
```

Dorénavant, sur Github, vos commits seront marqués d'un petit encart vert "verified". De même sur votre terminal pour pouvez vérifier dans les logs les commits signés :

> git log --show-signature -5

```
commit 67ff2326d2ea9f6d86c582f6c842bee7a95de9d1 (HEAD -> master, origin/master)
gpg: Signature faite le Jeu 17 sep 16:15:16 2020 CEST
gpg:                avec la clef RSA XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
gpg: Bonne signature de « user <user@mail.com> » [ultime]
Author: user <user@mail.com>
Date:   Thu Sep 17 16:15:16 2020 +0200

    signed commit
```

Personnellement, j'ai ajouté à mon .zshrc ce petit alias _glog='git log --pretty="format:%h %G? %aN %d %s"'_ :

```
$ git log --pretty="format:%h %G? %aN %d %s
12ddb92 G user   signed commit
5855463 G user   signed commit
0b867fc N user   non signed commit
887a067 N user   non signed commit
d45be7b N user   non signed commit
```

Si le commit est signé il sera alors accompagné de l'option G sinon l'option sera N.

## 5 - Plus de sécurité

Il est important de créer un certificat de révocation de votre clef secrète. Car si celle-ci est compromise ou perdue ce certificat est alors le seul moyen de dire aux autres d'ignorer la clef volée.

> gpg --output \<user@mail.com\>.gpg-revocation-certificate --gen-revoke XXXXXXXXXXXXXXX

On peut aussi faire une sauvegarde des paires de clefs en les exportant :

> gpg --export-secret-keys --armor XXXXXXXXXXXXXXX > \<user@mail.com\>.private.gpg-key

> gpg --export --armor XXXXXXXXXXXXXXX > \<user@mail.com\>.public.gpg-key

Surtout ne stockez pas le certificat et la clef secrète au même endroit.


**Bonus de fin**

On va finir par une petite astuce. Les commandes git merge et git pull peuvent vérifier et rejeter si nécessaire les commits non signés avec l'option --verify-signatures.

Par exemple, la fusion ne s'effectuera que si tous les commits sont signés

> git merge --verify-signatures -S non-verify

```
fatal: Commit e9c079b does not have a GPG signature.
```