DEV Community

M_S_360
M_S_360

Posted on

A Practical Guide to Managing Multiple Git Accounts with SSH

When you only have one account, using Git is easy—until you add more.
Perhaps you organize coursework on Bitbucket, work with your team on GitLab, and contribute to open source on GitHub. All of a sudden, your Git IDs, SSH keys, and credentials begin to clash.

From the straightforward scenario of one account to a complex multi-account configuration, this tutorial takes you step-by-step through the management of SSH keys and Git identities across several accounts.

The Simple Case: One Git Account

If you only use one Git account, life is easy.

Generate an SSH key:

ssh-keygen -t ed25519 -C "you@example.com"
Enter fullscreen mode Exit fullscreen mode

Add the key to your Git provider.

Copy your public key and paste it in your account settings:

cat ~/.ssh/id_ed25519.pub
Enter fullscreen mode Exit fullscreen mode

Test your connection:

ssh -T git@github.com
Enter fullscreen mode Exit fullscreen mode

You should see something like:

Hi username! You've successfully authenticated.
Enter fullscreen mode Exit fullscreen mode

With one account, Git will automatically use this single SSH key. You’re done.

The Real World: Multiple Git Accounts

Once you manage multiple accounts, things get complicated:

  • Personal GitHub for side projects

  • Work Gitlab for company code

  • Another Work Github for another company project

  • School Bitbucket for academic repositories

Each service should have its own SSH key, so that:

  • You avoid identity confusion (wrong commits under the wrong name)

  • Access permissions remain separate

  • Your personal and professional lives stay cleanly divided

First Step: Create Separate SSH Keys

Let’s generate one SSH key per account:

# Personal GitHub
ssh-keygen -t ed25519 -C "personal@example.com" -f ~/.ssh/id_ed25519_github

# Work GitLab
ssh-keygen -t ed25519 -C "work@example.com" -f ~/.ssh/id_ed25519_gitlab_work

# Another Work Github
ssh-keygen -t ed25519 -C "work2@example.com" -f ~/.ssh/id_ed25519_github_work


# School Bitbucket
ssh-keygen -t ed25519 -C "school@example.edu" -f ~/.ssh/id_ed25519_bitbucket
Enter fullscreen mode Exit fullscreen mode

You’ll now have files like these:

~/.ssh/
├── id_ed25519_github
├── id_ed25519_github.pub
├── id_ed25519_gitlab_work
├── id_ed25519_gitlab_work.pub
├── id_ed25519_github_work
├── id_ed25519_github_work.pub
├── id_ed25519_bitbucket
└── id_ed25519_bitbucket.pub
Enter fullscreen mode Exit fullscreen mode

Add each public key (.pub file) to the matching Git account.

Verifying that you can SSH into respective accounts

ssh -i ~/.ssh/id_ed25519_github git@github.com
ssh -i ~/.ssh/id_ed25519_gitlab_work git@gitlab.com
ssh -i ~/.ssh/id_ed25519_github_work git@github.com
ssh -i ~/.ssh/id_ed25519_bitbucket git@bitbucket.org
Enter fullscreen mode Exit fullscreen mode

However, having to explicitly specify your ssh keys everytime is not particularly exciting and easy to forget.

Using ssh-agent: A Quick Way to Handle Multiple Keys

That’s where ssh-agent helps — it securely stores your decrypted private keys in memory.

Start the agent and add your keys:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_github
ssh-add ~/.ssh/id_ed25519_gitlab_work
ssh-add ~/.ssh/id_ed25519_github_work
ssh-add ~/.ssh/id_ed25519_bitbucket
Enter fullscreen mode Exit fullscreen mode

Check that your keys are loaded:

ssh-add -l
Enter fullscreen mode Exit fullscreen mode

Now you can connect to your repositories without re-entering passwords every time.

However, the ssh-agent only runs for your current login or terminal session.
If you restart your system, log out, or even open a new terminal, the agent may not remember your loaded keys.
You’ll need to re-run the following code everytime you start a terminal session:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_github
# further run ssh-add for every other keys we generated
Enter fullscreen mode Exit fullscreen mode

(On Linux) To make it persistent, you can use a desktop keyring manager (like gnome-keyring), or configure your shell startup files (~/.bashrc, ~/.zshrc) to start and load your keys automatically.

Automate Key Selection with SSH Config (The Savior Step)

Create ~/.ssh/config file (if not already present) or add the following entries to it (if it already exists):

# Personal GitHub
Host github.com-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github
  IdentitiesOnly yes


# Work GitLab
Host gitlab.com-work
  HostName gitlab.com
  User git
  IdentityFile ~/.ssh/id_ed25519_gitlab_work
  IdentitiesOnly yes


# Work Github
Host github.com-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_github_work
  IdentitiesOnly yes


# School Bitbucket
Host bitbucket.org-school
  HostName bitbucket.org
  User git
  IdentityFile ~/.ssh/id_ed25519_bitbucket
  IdentitiesOnly yes

Enter fullscreen mode Exit fullscreen mode

Now, use the aliases when cloning repositories, as per defined in your ~/.ssh/config file:

# Personal
git clone git@github.com-personal:username/personal-repo.git

# Work Gitlab
git clone git@gitlab.com-work:company/work-gitlab-repo.git

# Work Github
git clone git@github.com-work:company/work-github-repo.git


# School
git clone git@bitbucket.org-school:university/coursework.git
Enter fullscreen mode Exit fullscreen mode

Now you can clone, pull and push your changes to Git Hosting Platforms without worrying about specifying the ssh private key explicitly or starting ssh-agent on every terminal session.

Bonus Tip

Always configure your Git username and email before making any commits — it saves you from headaches later. After cloning a repository, set your local username and email with the following commands:

git config --local user.name "your_name"
git config --local user.email "your_email"
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
anchildress1 profile image
Ashley Childress

This a great overview, thanks! Have you ever worked with the includeIf config option? I've found that it's sometimes easier to work with (although not as streamlined as your approach).

The tradeoff for me is I can work in either my git_work or git_personal directories with the exact same commands. Git handles the context switching for me based on the includeIf setting, which pulls a sub-config file based on the repo's directory location. If you're only supporting two, it's not a terrible setup. I have one common config plus two separate sub-configs each with a different email address, gpgKey, and ssh command (the later really just points to the right ssh key).