---
title: "How to manage multiple SSH keys for multiple GitHub accounts on one computer"
url: "https://alex.zappa.dev/blog/how-to-manage-multiple-ssh-keys-for-multiple-github-accounts-on-one-computer/"
description: "Learn how to set up and manage multiple SSH keys on a single computer to seamlessly work with multiple GitHub accounts. Step-by-step guide for developers."
---

# How to manage multiple SSH keys for multiple GitHub accounts on one computer

December 6, 2024

*   [#git](/tags/git/),
*   [#ssh](/tags/ssh/),
*   [#github](/tags/github/)

Recently [my son](https://zapparov.dev) asked me how to manage multiple SSH keys for multiple GitHub accounts on one computer. He’s starting his journey as a computer science student and needs to work with multiple GitHub accounts for his projects.

My first attempt was to find an article or ready solution to point him to. But I couldn’t find a good one. So I decided to write this article to help him and other developers who’re facing the same issue.

![How to Manage Multiple SSH Keys for Multiple GitHub Accounts on One Computer](/_astro/laptop-keys.CR8_Dfwv_ZVjS3r.webp)

## Step-by-step guide

### 1\. Generate two SSH keys

If you haven’t already, [generate two SSH keys](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) for each GitHub account:

```
ssh-keygen -t ed25519 -C "personal_email_account@example.com" -f ~/.ssh/id_ed25519_personal
ssh-keygen -t ed25519 -C "student_email_account@example.com" -f ~/.ssh/id_ed25519_edu
```

*   The `-f` flag specifies the filename for the keys (e.g., id\_ed25519\_personal and id\_ed25519\_edu).

> _**If you are using a legacy system that doesn’t support the Ed25519 algorithm, use:**_
> 
> ```
> ssh-keygen -t rsa -b 4096 -C "personal_email_account@example.com" -f ~/.ssh/id_rsa_personal
> ssh-keygen -t rsa -b 4096 -C "student_email_account@example.com" -f ~/.ssh/id_rsa_edu
> ```

### 2\. Add keys to the SSH agent

Add both keys to your SSH agent:

```
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_personal
ssh-add ~/.ssh/id_ed25519_edu
```

### 3\. Update the SSH config file

Edit (or create) your ~/.ssh/config file to define configurations for each GitHub account.

```
# GitHub Personal Account
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
  IdentitiesOnly yes

# GitHub Education Account
Host github.edu
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_edu
  IdentitiesOnly yes
```

> _**Why `IdentitiesOnly yes` matters:**_
> 
> Without it, SSH will offer every key loaded in your `ssh-agent` (and every `IdentityFile` that matches the host) in order. GitHub accepts the **first valid key** it receives — so if your personal key happens to be offered first, you’ll authenticate as your personal account even when connecting via `github.edu`. Setting `IdentitiesOnly yes` tells SSH to use only the key you explicitly specified for that host, which is what you almost certainly want when juggling multiple accounts on the same hostname.

### 4\. Use configured hosts in Git URLs

When cloning or working with Git repositories, use the corresponding host name defined in the SSH config:

For Personal account:

```
git clone git@github.com:username/repo.git
```

For Education account:

```
git clone git@github.edu:username/repo.git
```

### 5\. Test your configuration

Verify the setup by testing the SSH connection for each account:

```
ssh -T github.com
ssh -T github.edu
```

If the setup is correct, GitHub will identify each account and display a success message.

## Tips

If you already cloned repositories using the default [git@github.com](mailto:git@github.com) format, update the origin remote URL to use the appropriate host:

```
git remote set-url origin git@github.edu:username/repo.git
```

Make sure the SSH public keys (id\_ed25519\_personal.pub and id\_ed25519\_edu.pub) are added to the respective GitHub accounts in their settings.

### Avoid a catch-all `Host *` with `IdentityFile`

A lot of existing SSH configs end with a wildcard block like this:

```
Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519
```

The problem: `Host *` matches **every** host, including `github.edu`, and `IdentityFile` directives are **cumulative** across matching blocks. Your personal key gets appended to the identity list for every other host, the agent loads it, and it ends up offered first — bypassing the per-host key you carefully set up. Even `IdentitiesOnly yes` on the specific host won’t help, because the wildcard-added key is still considered “explicitly configured.”

Either remove the `IdentityFile` line from `Host *` (it’s the default anyway, so you don’t lose anything), or scope the wildcard down to the hosts that actually need it.

### Troubleshooting

If `ssh -T github.edu` still greets you with the **wrong** username, check:

1.  Run `ssh -v -T github.edu` and look at the `Offering public key:` and `Server accepts key:` lines — they tell you which key actually got used.
2.  Run `ssh-add -l` to see what’s loaded in your agent. If the personal key is there, `ssh-add -D` clears everything so only the keys your config points at get offered.
3.  Confirm the correct public key is uploaded to the matching GitHub account (a key can only be attached to one account at a time).

## Set up Git global configuration

To avoid conflicts, set up a global Git configuration for each account:

```
git config --global user.name "Personal Name"
git config --global user.email "personal_email_account@example.com"
```

then create a separate config file for the second account:

```
touch ~/.gitconfig_edu
echo "[user]" >> ~/.gitconfig_edu
echo "  name = Student Name" >> ~/.gitconfig_edu
echo "  email = student_email_account@example.com" >> ~/.gitconfig_edu
```

and then update the global configuration file `~/.gitconfig` to include the second configuration file:

```
echo "[includeIf \"gitdir:~/path/to/your/education/**\"]" >> ~/.gitconfig
echo "  path = ~/.gitconfig_edu" >> ~/.gitconfig
```

> _**Note: for Windows users ruleset `includeIf` could be different.**_
> 
> ```
> echo "[includeIf \"gitdir/i:C:/path/to/your/education/**\"]" >> ~/.gitconfig
> echo "  path = ~/.gitconfig_edu" >> ~/.gitconfig
> ```

This setup allows you to:

*   Use the correct name and email for each account.
*   Automatically switch between configurations based on the repository path.
*   Keep your global configuration clean and organized.

### How it works

When you run a Git command in a repository located in the `~/path/to/your/education/` directory, Git will use the configuration from the `~/.gitconfig_edu` file.

In all other cases, Git will use the default global configuration.

### Testing the configuration

To confirm the correct profile is being applied in a specific directory:

```
git config --get user.name
git config --get user.email
```

> _**Important notes:**_
> 
> *   The included files (e.g., `~/.gitconfig_edu`) must be valid Git configuration files.
> *   Make sure to replace `~/path/to/your/education/**` with the actual path to your education repositories.
> *   If a directory doesn’t match any includeIf condition, the global configuration will be used.

That’s it! You’ve successfully set up and managed multiple SSH keys for multiple GitHub accounts on one computer.

May the 4th be with you,  
Alex

*   [PreviouswebChronicle: your personal Wayback Machine](/blog/webchronicle/)
*   [Next Guest post on Orange Marketing: AIEO is the new SEO](/blog/aieo-orange-guest/)