Comment utiliser plusieurs comptes GitHub avec SSH

GitHub identifie votre compte grâce à la clé SSH : utilisez donc une clé par compte. Dans ~/.ssh/config, créez pour chacun un alias Host avec HostName github.com, son propre IdentityFile et IdentitiesOnly yes. Clonez ensuite avec l'alias, comme dans git clone git@github-work:org/repo.git. Utilisez includeIf dans Git pour définir la bonne adresse e-mail par dossier.

Mis à jour le . Configuration, Git et comportement de l'agent testés avec OpenSSH et Git 2.47 contre un serveur SSH local configuré pour se comporter comme GitHub : un seul utilisateur git, chaque clé étant associée à un nom de compte différent, avec de vrais clone et push.

Pourquoi cela demande une configuration

Chaque connexion à GitHub va vers le même hôte avec le même utilisateur, git. GitHub ne distingue les comptes que par la clé que vous présentez, et ssh s'arrête à la première clé que le serveur accepte. Il faut donc un moyen d'indiquer quelle clé utiliser pour quel dépôt. Les alias Host sont la solution habituelle.

1. Une clé par compte

ssh-keygen -t ed25519 -C "personal" -f ~/.ssh/id_ed25519_personal
ssh-keygen -t ed25519 -C "work" -f ~/.ssh/id_ed25519_work

Ajoutez chaque fichier .pub à son compte, comme dans ajouter une clé à GitHub.

2. Un alias pour chacun dans ~/.ssh/config

Host github-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Vérifiez ce que devient un alias, sans se connecter :

ssh -G github-work | grep -E '^(hostname|user|identityfile|identitiesonly) '

Testez ensuite chacun. Il doit vous saluer avec le bon nom d'utilisateur :

ssh -T git@github-personal
ssh -T git@github-work

Pourquoi IdentitiesOnly compte

Sans cette option, ssh essaie aussi toutes les clés de votre agent. Dans notre test, la clé indiquée dans la configuration était essayée en premier. Mais quand cette clé était refusée, ssh passait à une autre clé de l'agent et se connectait avec l'autre compte, sans aucune erreur. C'est ainsi qu'un push se retrouve sous le mauvais nom, ou qu'un dépôt semble introuvable. Avec IdentitiesOnly yes, le même test a échoué avec Permission denied, ce qui est ce que l'on veut. Cela évite aussi Too many authentication failures quand votre agent contient beaucoup de clés.

3. Utiliser l'alias dans l'adresse

Remplacez github.com par l'alias :

git clone git@github-work:org/repo.git

Pour un dépôt déjà cloné :

git remote set-url origin git@github-work:org/repo.git

Pour éviter de modifier les adresses que vous copiez depuis GitHub, Git peut les réécrire pour une organisation :

git config --global url."git@github-work:org/".insteadOf "git@github.com:org/"

4. Le bon nom sur vos commits

La clé SSH décide qui pousse. Vos commits portent ce que dit user.email, qui est un réglage distinct. Gardez les dépôts de travail dans un même dossier et ajoutez ceci à ~/.gitconfig :

[user]
    name = Your Name
    email = you@example.com

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work

Et dans ~/.gitconfig-work :

[user]
    email = you@work.example.com

Gardez la barre oblique finale dans gitdir:~/work/ : c'est elle qui fait correspondre tout ce qui se trouve à l'intérieur. Vérifiez depuis l'intérieur d'un dépôt :

cd ~/work/some-repo
git config user.email

Lancez cette commande dans un dépôt : dans notre test, le simple dossier ~/work affichait toujours l'adresse e-mail globale, car la condition dépend de l'emplacement du dépôt.

Alternative : choisir la clé par dossier, sans alias

Mettez la clé dans le même fichier inclus, et gardez les adresses normales github.com :

[core]
    sshCommand = ssh -i ~/.ssh/id_ed25519_work -o IdentitiesOnly=yes

Cela ne s'applique qu'une fois que Git se trouve dans un dépôt de ce dossier. Le premier clone demande donc de définir la clé à la main, ce qui est aussi la méthode ponctuelle documentée par GitHub :

GIT_SSH_COMMAND='ssh -i ~/.ssh/id_ed25519_work -o IdentitiesOnly=yes' git clone git@github.com:org/repo.git

Si vous préférez cibler l'adresse du dépôt plutôt que son dossier, Git 2.36 et les versions suivantes acceptent aussi des conditions comme [includeIf "hasconfig:remote.*.url:git@github-work:*/**"].

Si cela se passe mal

  • "Repository not found" avec la bonne adresse. Vous êtes probablement authentifié avec l'autre compte. Lancez ssh -T avec l'alias et lisez le nom.
  • Quelle clé est vraiment utilisée. ssh -vT git@github-work affiche chaque clé proposée.
  • Permission denied. Voir Permission denied (publickey) avec Git.

Questions

Puis-je utiliser la même clé pour les deux comptes ?

Non. GitHub refuse une clé déjà associée à un autre compte, avec l'erreur Key already in use.

Ai-je encore besoin de l'alias si j'utilise core.sshCommand ?

Non. L'un ou l'autre suffit pour choisir la clé. L'alias est visible dans l'adresse du dépôt distant, alors que core.sshCommand garde l'adresse normale github.com, ce qui est pratique pour les scripts qui l'attendent.

Sources

Autres guides : Configuration et nombreux serveurs

Tous les guides