Git avancé : sécurité et configuration
Signer ses commits
Section intitulée « Signer ses commits »Un commit porte un nom et un e-mail déclaratifs : n’importe qui peut en écrire d’autres. Une signature prouve que le commit vient bien de la personne qui détient la clé.
Signature avec une clé SSH (simple)
Section intitulée « Signature avec une clé SSH (simple) »ssh-keygen -t ed25519 -f ~/.ssh/id_signature -C "signature git" # voir « SSH : clés »git config --global gpg.format sshgit config --global user.signingkey ~/.ssh/id_signature.pubgit config --global commit.gpgsign truegit config --global tag.gpgSign truePour vérifier localement les signatures SSH, un fichier des signataires autorisés :
echo "alice@exemple.com $(cat ~/.ssh/id_signature.pub)" >> ~/.config/git/allowed_signersgit config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signersgit log --show-signature -3git verify-commit HEADAjouter ensuite la clé publique de signature dans le profil du serveur (Gitea : paramètres du compte, clés SSH/GPG, usage « signature ») pour obtenir la mention Vérifié sur les commits. Voir SSH : clés.
Signature avec GPG
Section intitulée « Signature avec GPG »sudo apt install gnupggpg --full-generate-key # ed25519 recommandé, durée de validitégpg --list-secret-keys --keyid-format=longgit config --global user.signingkey <IDENTIFIANT_DE_CLE>git config --global commit.gpgsign truegit commit -S -m "feat: signé"export GPG_TTY=$(tty) # nécessaire pour la saisie de la phrase secrète dans un terminal| SSH | GPG | |
|---|---|---|
| Mise en place | Réutilise l’outillage SSH | Installation et gestion d’un trousseau |
| Révocation, expiration | Limitées | Complètes |
| Pour un usage individuel ou d’équipe réduite | Recommandé | Si l’organisation l’exige |
La signature n’est utile que si elle est vérifiée (serveur, politique de branche) ; sinon c’est un simple décor.
Un secret a été commité
Section intitulée « Un secret a été commité »Retirer un fichier de tout l’historique avec git filter-repo (outil officiellement recommandé, plus sûr que filter-branch) :
sudo apt install git-filter-repogit clone --mirror https://git.exemple.com/depot.git depot-nettoyage.git # copie de travailcd depot-nettoyage.git
git filter-repo --invert-paths --path config/secrets.env # supprimer un fichier de l'historiquegit filter-repo --replace-text <(printf 'MonMotDePasse==>***SUPPRIME***\n') # remplacer un texte partoutgit filter-repo --path-glob '*.pem' --invert-paths # tous les fichiers .pem
git push --force --mirror # réécrit le dépôt distantConséquences à gérer :
| Point | Action |
|---|---|
| Tous les commits changent d’identifiant | Chaque contributeur doit reclonner (ne pas fusionner l’ancien historique, qui réintroduirait le secret) |
| Demandes de fusion ouvertes | À recréer |
| Cache du serveur | Demander la purge (Gitea : gitea admin / ramasse-miettes ; plateformes en ligne : support) |
| Étiquettes | Réécrites aussi |
| Copies existantes | Considérer le secret comme compromis |
Éviter le problème : hooks de détection de secrets, .gitignore pour .env, analyse en intégration continue.
Détecter des secrets
Section intitulée « Détecter des secrets »sudo apt install gitleaks # si disponible, sinon binaire officielgitleaks detect --source . --redact # analyse l'historiquegitleaks protect --staged --redact # analyse l'index (hook pre-commit)git log -p | grep -iE "(password|secret|token|api[_-]?key)\s*[:=]" # recherche sommaireConfiguration : trois niveaux
Section intitulée « Configuration : trois niveaux »| Niveau | Fichier | Portée |
|---|---|---|
| Système | /etc/gitconfig |
Tous les utilisateurs |
| Global | ~/.gitconfig (ou ~/.config/git/config) |
Un utilisateur |
| Local | .git/config |
Un dépôt |
git config --list --show-origingit config --global --editgit config user.email # valeur effectivegit config --unset user.emailLe niveau le plus précis l’emporte (local > global > système).
Réglages recommandés
Section intitulée « Réglages recommandés »git config --global init.defaultBranch maingit config --global pull.rebase truegit config --global fetch.prune truegit config --global push.autoSetupRemote truegit config --global rebase.autoStash truegit config --global rebase.autoSquash truegit config --global rebase.updateRefs truegit config --global merge.conflictStyle zdiff3git config --global rerere.enabled truegit config --global diff.algorithm histogramgit config --global diff.colorMoved defaultgit config --global commit.verbose truegit config --global branch.sort -committerdategit config --global tag.sort version:refnamegit config --global help.autocorrect promptgit config --global core.editor "nano"git config --global core.pager "less -FRX"git config --global column.ui autoCertains réglages dépendent de la version de Git : git config ne signale pas toujours une clé inconnue ; vérifier avec git config --get <clé> et la documentation de la version installée.
Configuration par dossier : includeIf
Section intitulée « Configuration par dossier : includeIf »Utiliser une identité différente selon le dossier (personnel et professionnel) :
[user] name = Alice Martin email = alice@exemple.com
[includeIf "gitdir:~/projets/travail/"] path = ~/.gitconfig-travail
[includeIf "hasconfig:remote.*.url:git@git.entreprise.example:**"] path = ~/.gitconfig-travail[user] email = alice.martin@entreprise.example signingkey = ~/.ssh/id_travail.pubLa première règle s’applique aux dépôts situés sous ~/projets/travail/, la seconde à ceux dont l’adresse distante correspond (selon la version de Git). Évite d’utiliser par erreur une adresse e-mail personnelle sur un projet professionnel.
git config --global alias.st "status -sb"git config --global alias.co "switch"git config --global alias.br "branch -vv"git config --global alias.lg "log --graph --oneline --decorate --all -30"git config --global alias.dernier "log -1 --stat"git config --global alias.annuler "reset --soft HEAD~1"git config --global alias.fixup "commit --fixup"git config --global alias.nettoyer '!git fetch --prune && git branch --merged main | grep -v "main" | xargs -r git branch -d'Un alias commençant par ! exécute une commande shell. Choisir des alias qui ne masquent pas les noms des commandes habituelles : un alias dangereux (git config alias.push "push --force") cause des accidents.
.gitattributes
Section intitulée « .gitattributes »* text=auto eol=lf*.sh text eol=lf*.bat text eol=crlf*.png *.jpg *.pdf binarypackage-lock.json -diff merge=binary*.min.js -diffdocs/** linguist-documentationCHANGELOG.md merge=union| Attribut | Rôle |
|---|---|
text=auto eol=lf |
Fins de ligne normalisées (lf) : plus de fichiers « modifiés » à cause de crlf |
binary |
Ne pas comparer ni fusionner comme du texte |
-diff |
Ne pas afficher le contenu dans git diff (fichiers générés) |
merge=union |
Fusion en conservant les lignes des deux côtés |
export-ignore |
Exclure de git archive |
filter=lfs |
Git LFS (Gros dépôts et sous-projets) |
Après modification : git add --renormalize ..
Authentification
Section intitulée « Authentification »git config --global credential.helper cache --timeout=3600 # mémoire pendant 1 hgit config --global credential.helper store # fichier en CLAIR (déconseillé)git config --global credential.helper libsecret # trousseau du système (bureau)git remote set-url origin git@git.exemple.com:equipe/projet.git # passer en SSH| Méthode | Conseil |
|---|---|
| Clé SSH | Recommandé : pas de mot de passe réutilisable (SSH : clés) |
| Jeton d’accès (HTTPS) | Droits minimaux, durée limitée, stocké par un assistant d’identifiants (pas dans l’URL) |
credential.helper store |
Mot de passe en clair dans ~/.git-credentials : à éviter |
Ne jamais mettre un jeton dans l’adresse distante (https://jeton@…) : il resterait dans .git/config et l’historique du shell.
Sécurité des dépôts
Section intitulée « Sécurité des dépôts »| Sujet | Réglage |
|---|---|
fatal: detected dubious ownership in repository |
Le dépôt appartient à un autre utilisateur : git config --global --add safe.directory /chemin/du/depot (seulement pour un dépôt de confiance) |
| Exécution de code par un dépôt cloné | Les hooks et les filtres d’un dépôt inconnu peuvent exécuter des commandes : ne pas lancer git de confiance dans un dépôt non vérifié avec des droits élevés |
transfer.fsckObjects |
git config --global transfer.fsckObjects true : vérifier l’intégrité à la réception |
| Protocoles | protocol.file.allow user : limiter les protocoles de sous-modules |
| Poussées forcées | Branches protégées sur le serveur |
Les hooks locaux (pre-commit, commit-msg, pre-push) se gèrent avec Husky ou core.hooksPath :
git config core.hooksPath .githooksVoir Husky : installation et Husky : hooks Git natifs. Côté serveur, les protections de branche et les vérifications de la CI font autorité.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
error: gpg failed to sign the data |
GPG_TTY non défini, agent GPG arrêté (gpgconf --kill gpg-agent), clé introuvable |
| Commits « Non vérifié » sur le serveur | Clé de signature absente du profil, ou adresse e-mail différente de celle de la clé |
error: Load key … invalid format (signature SSH) |
Mauvais chemin : user.signingkey doit pointer vers la clé publique .pub |
filter-repo : Refusing to destructively overwrite repo history |
Travailler sur un clone frais (--mirror) ou ajouter --force en connaissance de cause |
| Le secret réapparaît après la réécriture | Un collègue a repoussé l’ancien historique : reclonage obligatoire |
| Une option de configuration est ignorée | Version de Git trop ancienne ; git config --get <clé> ; orthographe |
| Fins de ligne qui changent | .gitattributes (* text=auto eol=lf), git add --renormalize . |
Permission denied (publickey) |
Clé SSH non chargée (ssh-add -l) ou non enregistrée sur le serveur |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Les versions de Git diffèrent : certains réglages récents (zdiff3, rebase.updateRefs, push.autoSetupRemote, branch.sort) demandent des versions récentes ; git --version et git config --get <clé> permettent de vérifier. Les paquets git-lfs, git-filter-repo et gnupg sont disponibles dans les dépôts d’Ubuntu. Sur 26.04, sudo est fourni par sudo-rs (sans effet sur Git).
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Signer son travail (Pro Git), git filter-repo, Configuration de Git
- Retour : Rebase et réécriture de l’historique