Cómo usar varias cuentas de GitHub con SSH

GitHub identifica tu cuenta por la clave SSH, así que usa una clave por cuenta. En ~/.ssh/config, crea un alias Host para cada una con HostName github.com, su propio IdentityFile e IdentitiesOnly yes. Luego clona con el alias, como en git clone git@github-work:org/repo.git. Usa includeIf en Git para fijar el email correcto por carpeta.

Actualizada el . El comportamiento de la configuración, de Git y del agente se probó con OpenSSH y Git 2.47 contra un servidor SSH local configurado para actuar como GitHub: un único usuario git, con cada clave asociada a un nombre de cuenta distinto, incluidos clone y push reales.

Por qué esto necesita configuración

Toda conexión a GitHub va al mismo host con el mismo usuario, git. GitHub distingue las cuentas solo por la clave que presentas, y ssh se detiene en la primera clave que el servidor acepta. Necesitas, por tanto, una forma de indicar qué clave usar para cada repositorio. Los alias de Host son la forma habitual.

1. Una clave por cuenta

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

Añade cada archivo .pub a su cuenta, como en añadir una clave a GitHub.

2. Un alias para cada una en ~/.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

Comprueba a qué se resuelve un alias, sin conectar:

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

Luego prueba cada uno. Debería saludarte con el nombre de usuario correcto:

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

Por qué importa IdentitiesOnly

Sin ello, ssh también prueba todas las claves de tu agente. En nuestra prueba, la clave indicada en la configuración se probó primero. Pero cuando esa clave fue rechazada, ssh pasó a otra clave del agente e inició sesión como la otra cuenta, sin ningún error. Así es como un push acaba con el nombre equivocado, o un repositorio parece no existir. Con IdentitiesOnly yes, la misma prueba falló con Permission denied, que es lo que quieres. También evita Too many authentication failures cuando tu agente tiene muchas claves.

3. Usa el alias en la dirección

Sustituye github.com por el alias:

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

Para un repositorio que ya clonaste:

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

Para no tener que cambiar las direcciones que copias de GitHub, Git puede reescribirlas para una organización:

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

4. El nombre correcto en tus commits

La clave SSH decide quién hace el push. Tus commits llevan lo que diga user.email, que es un ajuste aparte. Mantén los repositorios de trabajo en una carpeta y añade esto a ~/.gitconfig:

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

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

Y en ~/.gitconfig-work:

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

Conserva la barra final en gitdir:~/work/, que es lo que hace que coincida con todo lo que hay dentro. Compruébalo desde dentro de un repositorio:

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

Ejecútalo dentro de un repositorio: en nuestra prueba, la carpeta ~/work a secas seguía mostrando el email global, porque la condición depende de la ubicación del repositorio.

Alternativa: elegir la clave por carpeta, sin alias

Pon la clave en el mismo archivo incluido y conserva las direcciones normales de github.com:

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

Solo se aplica cuando Git está dentro de un repositorio de esa carpeta. Así que el primer clone necesita la clave indicada a mano, que es también el método puntual documentado por GitHub:

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

Si prefieres coincidir por la dirección del repositorio y no por su carpeta, Git 2.36 y posteriores también aceptan condiciones como [includeIf "hasconfig:remote.*.url:git@github-work:*/**"].

Si algo sale mal

  • "Repository not found" con la dirección correcta. Probablemente estás autenticado como la otra cuenta. Ejecuta ssh -T con el alias y lee el nombre.
  • Qué clave se usa realmente. ssh -vT git@github-work imprime cada clave que ofrece.
  • Permission denied. Mira Permission denied (publickey) con Git.

Preguntas

¿Puedo usar una misma clave para las dos cuentas?

No. GitHub rechaza una clave que ya está en otra cuenta, con el error Key already in use.

¿Sigo necesitando el alias si uso core.sshCommand?

No. Con cualquiera de los dos basta para elegir la clave. El alias es visible en la dirección del remoto, y core.sshCommand mantiene la dirección normal de github.com, que resulta cómoda para scripts que la esperan.

Fuentes

Más en Configuración y muchos servidores

Todas las guías