Struggling with Permission denied (publickey) when switching GitHub accounts?
This guide shows you how to configure multiple GitHub accounts using SSH keys, host aliases, and automatic Git identity switching.
Set it up once. It works forever.
π Quick Setup (TL;DR)
If you already understand SSH basics, hereβs the entire flow:
# 1. Create two SSH keys
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_ed25519_work
ssh-keygen -t ed25519 -C "personal@email.com" -f ~/.ssh/id_ed25519_personal
# 2. Configure SSH aliases
# ~/.ssh/config
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
# 3. Clone using aliases
git clone git@github-work:org/repo.git
git clone git@github-personal:user/repo.git
π If this makes sense, youβre done
π If not, continue for the full breakdown
The Problem
You have:
- One work GitHub account
- One personal GitHub account
But SSH only sees:
github.com
So when you push code, it guesses which key to use. Sometimes it guesses wrong.
Result:
Permission denied (publickey)
The Core Insight (Most Tutorials Miss This)
You are configuring two completely separate systems:
| System | Responsibility |
|---|---|
| SSH | Authentication (which GitHub account you are) |
| Git config | Commit identity (name and email) |
They do not sync automatically.
This is why:
- You can authenticate as work
- But commit as personal
Mental Model
Git β SSH Alias β SSH Key β GitHub Account
github-work β id_ed25519_work β Work GitHub
github-personal β id_ed25519_personal β Personal GitHub
Step 1. Open Terminal
- macOS β Terminal / VS Code terminal
- Windows β Git Bash (recommended)
Step 2. Organize Repositories
mkdir -p ~/projects/work
mkdir -p ~/projects/personal
This enables automatic Git identity switching later.
Step 3. Generate SSH Keys
ssh-keygen -t ed25519 -C "work@company.com" -f ~/.ssh/id_ed25519_work
ssh-keygen -t ed25519 -C "personal@example.com" -f ~/.ssh/id_ed25519_personal
Each creates:
- Private key (never share)
- Public key (upload to GitHub)
Step 4. Configure SSH (Critical Step)
Edit:
nano ~/.ssh/config
macOS Configuration (with Keychain)
# Global settings (required for persistence)
Host *
AddKeysToAgent yes
UseKeychain yes
# Work account
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
# Personal account
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
Windows Configuration
Host *
AddKeysToAgent yes
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
Why aliases are required
Without aliases:
git@github.com
SSH cannot determine which key to use.
With aliases:
git@github-work
git@github-personal
SSH uses the correct key deterministically.
Step 5. Add Keys to SSH Agent
macOS
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_personal
Windows (Git Bash)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_work
ssh-add ~/.ssh/id_ed25519_personal
macOS Keychain (Important)
-
UseKeychain yesenables secure storage -
--apple-use-keychainpersists keys across restarts
Without this:
- Keys are lost after reboot
- Youβll be prompted repeatedly
Step 6. Add Public Keys to GitHub
Copy keys
macOS:
pbcopy < ~/.ssh/id_ed25519_work.pub
Windows:
clip < ~/.ssh/id_ed25519_work.pub
Add in GitHub
- Profile β Settings β SSH and GPG keys β New SSH key
-
Add separately for:
- Work account
- Personal account
Step 7. Test Connections
ssh -T git@github-work
ssh -T git@github-personal
Expected:
Hi <username>! You've successfully authenticated...
Step 8. Automatic Git Identity Switching
Edit:
nano ~/.gitconfig
[user]
name = Your Work Name
email = work@company.com
[includeIf "gitdir:~/projects/personal/"]
path = ~/.gitconfig-personal
Create:
nano ~/.gitconfig-personal
[user]
name = Your Personal Name
email = personal@example.com
How it works
if repo β ~/projects/personal/
β use personal identity
else
β use work identity
Step 9. Clone Repositories Correctly
# Work
git clone git@github-work:company/project.git
# Personal
git clone git@github-personal:username/project.git
Fix existing repositories
git remote set-url origin git@github-work:company/repo.git
Step 10. Verify Setup
git config user.name
git config user.email
Common Issues and Fixes
Permission denied (publickey)
Cause:
github.com used instead of alias
Fix:
git remote set-url origin git@github-work:org/repo.git
Wrong commit identity
git config user.email
Check:
- Folder structure
- includeIf configuration
macOS Keychain not working
Ensure:
Host *
AddKeysToAgent yes
UseKeychain yes
Re-run:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
Windows keys not persisting
PowerShell (Admin):
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
Then:
ssh-add ~/.ssh/id_ed25519_work
Quick Reference
| Item | Work | Personal |
|---|---|---|
| SSH alias | github-work | github-personal |
| Key | id_ed25519_work | id_ed25519_personal |
| Folder | ~/projects/work | ~/projects/personal |
| Clone | git@github-work | git@github-personal |
Final Thoughts
This setup:
- Eliminates SSH conflicts
- Automates identity switching
- Keeps work and personal environments cleanly separated
One-time setup. Long-term reliability.
If This Helped
- Save this for future setups
- Share it with your team
Top comments (0)