None

Managing Multiple GitHub Accounts with SSH Keys

A step-by-step guide to configuring SSH for seamless pushes to different GitHub remote repositories across accounts on macOS.

Background

I have multiple GitHub accounts: one for public projects, another for my private work. To be able to push from my local repositories to their respective remotes across accounts, a little configuration is required. This article will look at how to accomplish this assuming macOS working from a Zsh shell.

 

Shell

The commands in this article are tested in Zsh.

Solution

To get working with multiple accounts, we're going to need to execute a couple of steps:

  1. Generate SSH keys & share public keys with GitHub,
  2. Configure SSH, and
  3. Configure remotes.

Let's get to work.

SSH Keys

To authenticate with GitHub, you're going to need SSH keys. "But I use HTTPS!" Stop yelling. We use SSH in this household.

First, let's take a look at what SSH keys we're working with.

# list existing SSH keys

ls -l ~/.ssh

You could use your generic SSH key (e.g., ~/.ssh/id_rsa) for one of the accounts, but I like to create dedicated keys. By using dedicated keys, I reduce the risk of unintentionally breaking other services when rolling keys.

I have existing keys for my GitHub account so I'm going to go ahead and delete those to prove to both myself and the world I'm capable of doing this by recall.

# remove keys

rm ~/.ssh/<key> ~/.ssh/<key>.pub

Remember, keys come in pairs so delete both. With a clean start, let's make those keys.

I'm using ssh-keygen to create SSH keys. Use this utility with the following pattern:

# create keys

ssh-keygen -t <key-type> -C "<comment>" -f <output-file>

As of this article's publication date of August 1, 2025 (and for some time before), GitHub wants you to use the ed25519 algorithm. That value is specified following the -t flag in the "key type" placeholder above.

For the comment, you can use the email associated with the GitHub account you intend to use the key with. However, this isn't strictly necessary and can be omitted. I personally just use the output file to indicate the key's purpose.

Altogether, this will look like the following:

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_<account-alias>

When you run the command, you'll be prompted for a passphrase. This isn't strictly necessary. You'll be able to authenticate without it. It does add a layer of security in case your keys are compromised. But considering entering your password again and again when making push and pull requests can become tedious, I tend not to use a passphrase for small projects.

 

Passphrase

Using a passphrase with your SSH keys will require you to enter your password when authenticating with the remote. Depending on your circumstances, this may or may not be desirable.

Last, the "account-alias" is just something to indicate the purpose of the key. I use my GitHub username in this case since I'm trying to associate a key with a particular account.

With that, you'll see a bit of gibberish output. Run a quick ls -l ~/.ssh to verify the keys were created as and where expected.

With keys in hand, let's head over to GitHub and input those public keys. Follow their documentation on how to do this. Currently, this is accessible with Settings > SSH & GPG keys > New SSH Key.

Now let's copy the public key before pasting it into the GitHub input field.

# copy ssh public key

cat ~/.ssh/id_ed25519_<account-alias>.pub | pbcopy

# OR

pbcopy < ~/.ssh/id_ed25519_<account-alias>.pub
 

DANGER

Always use the public key with the ".pub" extension. If accidentally exposed, re-create it!

I'm dumb and did exactly that, even though I've done this a thousand times, so I'll re-create mine before continuing.

With our first key now entered into GitHub's system, repeat the process until every account you need to authenticate with has its own key.

At this point, we could try the following to see if we can authenticate. But likely, we'll still need more configuration for this to work.

ssh -T git@github.com

We'll see how to do that next.

SSH Configuration

To get our SSH keys operational, we need to provide SSH configuration that instructs the SSH client running on your computer how to resolve which key to use. To access or create a config file:

# open ssh config

nano ~/.ssh/config

From here, we'll need to enter a couple of details for each key:

# ~/.ssh/config

Host github.com-<account-alias>
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_<account-alias>
    IdentitiesOnly yes

# repeat for every key

Here you can see where the magic with the account aliases comes in to play. The account alias we've been using and present in the "Host" block is what the SSH client to map connections to the correct key.

Now let's give our keys a test to see if everything is working.

# test ssh keys with GitHub

ssh -T git@github.com-<account-alias>

If all is well, you should be prompted for your passphrase associated with the SSH key (if you set up a passphrase), and receive the following response:

Hi <username>! You've successfully authenticated, but GitHub does not provide shell access.

If you run into issues with SSH, try restarting your SSH client or check your configuration.

Configure GitHub Remotes

We're on the home stretch now. The last step is to configure our remote connections in git. If you copy the URL pointing to your remote repository directly from GitHub it will not be correct. The URL provided comes in the form of git@github.com:<username>/<repo-name>.git. This is missing the account alias and therefore SSH will fail.

To fix this simply insert the alias following the host but before the username and preceding colon: git@github.com-<account-alias>:<username>/<repo-name>.git.

If you're adding the remote for the first time, use the following command:

# add new remote

git remote add origin git@github.com-<account-alias>:<username>/<repo-name>.git

If the URL is already in the system but you need to update it to account for the alias, use the following command:

# update URL

git remote set-url origin git@github.com-<account-alias>:<username>/<repo-name>.git

Now check your remotes were created/updated as expected:

# check remotes

git remote -v

With our remote repositories correctly configured, we should now be able to push and pull changes without SSH key conflicts, ensuring the correct GitHub account is used for each repository.

Other Considerations

We're now able to connect to GitHub but one small item still remains. We need to make sure the correct email is associated with our commits' metadata. If not, the commits won't register on our GitHub profile's activity graph. We need to make sure those little green squares are being tiled in or we may feel less than as engineers.

While this might seem trivial, it's something you might risk forgetting about when juggling multiple GitHub accounts. My preference is to set the global config to the account I use most often so I have to update repo-specific config less frequently.

git config --global user.email "<your-email>"

# following the convention
# git config [--scope] <key> <value>

Then at the repo set the exceptions.

# a repo for an account other than the 
#    one associated with the global email

git config user.email "<your-email>"

Just make sure your current working directory is somewhere within the repo's working tree.

Final Thoughts

While it would be nice if all your version control existed within a single GitHub account, life is messy. This discussion looked at how to manage multiple GitHub accounts using multiple SSH keys. We explored setting up and managing SSH keys, updating SSH config files, and configuring your local repositories' remotes to utilize specific keys based on aliases. By following these steps, you'll streamline your workflow across multiple GitHub accounts, saving time and avoiding common pitfalls like authentication errors. Cheers.

Details
Published
August 1, 2025
Next
April 8, 2025

Securely Update Kubernetes Secrets with Manual GitHub Workflows

A Step-by-Step Guide to Managing Environment Variables in DigitalOcean Kubernetes Using workflow_dispatch