This configuration avoids the common SSH pitfalls that cause authentication failures and wrong-identity commits.


ED25519 keys are faster and GitHub recommends them. All major platforms support ED25519 as of 2025. RSA keys still work but GitHub disabled RSA SHA-1 signatures in March 2022.
## Work account key - put it in a file you'll remember
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C \"work@company.com\"
## Personal account key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C \"personal@gmail.com\"
## Client key (if you're freelancing)
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_client -C \"freelance@client.com\"
Passphrase decision: SSH key passphrases add security but require typing every time the SSH agent dies (which happens every fucking Tuesday on Linux). For personal machines, skip them. For work laptops, use them because IT security will audit your shit. macOS Keychain integration breaks on every OS update - Monterey 12.3 completely fucked it, and Ventura 13.0 wasn't much better.
Step 2: Write the SSH Config That Doesn't Suck
Create or edit `~/.ssh/config`. This file might not exist yet - that's fine, just create it. Pay attention to the spacing - SSH config is picky about tabs vs spaces.
## Work GitHub - use this for company repos
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
AddKeysToAgent yes
## Personal GitHub - use this for your side projects
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
AddKeysToAgent yes
## If you use GitLab for work too
Host gitlab-work
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
AddKeysToAgent yes
The magic is in the details:
SSH config gotchas that will ruin your entire fucking day:
Step 3: Copy Your Public Keys Like a Human
Copy the public key contents to your clipboard and paste them into each Git service:
## Copy work key to clipboard (macOS)
pbcopy < ~/.ssh/id_ed25519_work.pub
## Linux version
xclip -selection clipboard < ~/.ssh/id_ed25519_work.pub
## Windows (Git Bash)
clip < ~/.ssh/id_ed25519_work.pub
## Or just display it and copy manually
cat ~/.ssh/id_ed25519_work.pub
Where to paste them:
- GitHub: GitHub.com → Settings → SSH and GPG keys → New SSH key
- GitLab: User Settings → SSH Keys → Add new key
- Bitbucket: Personal settings → SSH keys → Add key
Title the keys something useful like "MacBook Pro Work" or "Personal Laptop" so you remember which machine they're from when you need to rotate them.
Step 4: Fix Your Repository URLs
Change your existing repositories to use the SSH host aliases. If you're still using HTTPS URLs (the https://github.com/...
ones), this is why Git keeps asking for passwords.
## Check what you have now
git remote -v
## Fix work repositories to use work SSH alias
git remote set-url origin git@github-work:company/repo.git
## Fix personal repositories to use personal alias
git remote set-url origin git@github-personal:username/repo.git
Pro tip: For new clones, copy the SSH URL from GitHub but modify the hostname:
- GitHub gives you:
git@github.com:user/repo.git
- You want:
git@github-work:user/repo.git
or git@github-personal:user/repo.git
Step 5: Test It Before You Trust It
This is the step everyone skips and then wonders why nothing works:
## Test work connection - should show your work username
ssh -T git@github-work
## Test personal connection - should show your personal username
ssh -T git@github-personal
If you get "Permission denied (publickey)": This error message is about as helpful as a chocolate teapot. Run ssh -vT git@github-work
to see what SSH is actually trying and why it's failing spectacularly.
If it shows the wrong username: Congratulations, you just uploaded your personal key to your work account. We've all done this. Delete the key from the wrong account and upload it to the right one.
Step 6: Stop Fucking Up New Repository Clones
When you clone new repositories, use your SSH aliases instead of the default URLs:
## For work projects
git clone git@github-work:company/new-repo.git
## For personal projects
git clone git@github-personal:username/side-project.git
The gotcha: GitHub's clone button gives you git@github.com:...
- you need to change the hostname to your alias.
The Missing Piece: Git User Configuration
SSH handles authentication, but Git still needs to know your name and email for commits. Either set these per repository:
## In each work repository
git config user.email \"professional@company.com\"
git config user.name \"Professional Name\"
## In each personal repository
git config user.email \"personal@gmail.com\"
git config user.name \"Real Name\"
Or use Git conditional includes to automatically switch based on directory paths. But honestly, per-repo config is more reliable because you won't clone that emergency hotfix to the wrong folder at 2am when production is down.
When This Inevitably Breaks
Because SSH is SSH, here are the nuclear options for when nothing works:
SSH Agent Resurrection
If SSH stops working entirely, the agent probably died:
## Kill and restart ssh-agent
killall ssh-agent
eval \"$(ssh-agent -s)\"
## Re-add your keys
ssh-add ~/.ssh/id_ed25519_work
ssh-add ~/.ssh/id_ed25519_personal
## Check what's loaded
ssh-add -l
If SSH connections are slow, enable connection multiplexing:
## Add to ~/.ssh/config for faster connections
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 5m
You need to create the sockets directory first: mkdir -p ~/.ssh/sockets
Corporate Firewall Bypass
If your company blocks SSH (port 22), GitHub supports SSH over HTTPS:
## Add this to your work SSH config
Host github-work
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
This tunnels SSH through port 443, which corporate firewalls usually allow.
That's it. This setup works across macOS, Linux, and Windows (with Git Bash). It scales from 2 accounts to 20 accounts. Once it's working, you can forget about Git authentication entirely and focus on actually writing code.
That's the complete setup process. Once configured, this system handles multiple Git accounts automatically.