A clean, secure guide for using two different GitHub accounts on the same machine with automatic SSH key selection and Git identity management.
This setup automatically uses the correct GitHub account based on your working directory.
- macOS/Linux with SSH and Git installed
- Two GitHub accounts (personal and work)
- Basic familiarity with terminal commands
Follow GitHub's official SSH setup guide for detailed instructions.
Quick setup:
# Personal GitHub account (Ed25519)
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_github_personal
# Work GitHub account (Ed25519 or FIDO2 hardware token)
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519_github_workSecurity: Use passphrases for work keys. Consider FIDO2 hardware tokens for maximum security.
Critical: Lock down your SSH directory and keys:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config ~/.ssh/id_*This prevents accidental world-readable keys or configs.
echo "=== Personal GitHub Key ==="
cat ~/.ssh/id_ed25519_github_personal.pub
echo -e "\n=== Work GitHub Key ==="
cat ~/.ssh/id_ed25519_github_work.pub- Go to GitHub.com → Settings → SSH and GPG keys
- Click "New SSH key"
- Give it a descriptive title (e.g., "Personal MacBook" or "Work MacBook")
- Paste the appropriate public key
- Click "Add SSH key"
- Repeat for the second account
Create or edit ~/.ssh/config to add SSH aliases:
# Personal GitHub account (default port 22)
Host github-personal
HostName github.com
User git
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519_github_personal
UseKeychain yes
AddKeysToAgent yes
# Work GitHub account (default port 22)
Host github-work
HostName github.com
User git
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519_github_work
UseKeychain yes
AddKeysToAgent yes
# Alternative: If port 22 is blocked, use port 443
Host github-personal-443
HostName ssh.github.com
Port 443
User git
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519_github_personal
UseKeychain yes
AddKeysToAgent yes
Host github-work-443
HostName ssh.github.com
Port 443
User git
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519_github_work
UseKeychain yes
AddKeysToAgent yesIdentitiesOnly yes: Critical! This tells SSH to only use the specified key, not try other keys from the agent firstUseKeychain yes: Stores passphrases in macOS Keychain (macOS only - remove on Linux)AddKeysToAgent yes: Adds keys to SSH agent for convenienceHostName ssh.github.com: Required for SSH over port 443, notgithub.com- Port 22 vs 443: Use 22 by default; only use 443 if port 22 is blocked
Test both connections to ensure they're working:
# Test personal account
ssh -T github-personal
# Should show: Hi [your-personal-username]! You've successfully authenticated...
# Test work account
ssh -T github-work
# Should show: Hi [your-work-username]! You've successfully authenticated...Configure Git to automatically use the correct account and SSH key based on your working directory:
[user]
name = Your Personal Name
email = [email protected]
[includeIf "gitdir:/path/to/your/work/directory/"]
path = ~/.gitconfig-work
[url "git@github-personal:"]
insteadOf = https://github.com/
insteadOf = [email protected]:[user]
name = Your Work Name
email = [email protected]
[url "git@github-work:"]
insteadOf = https://github.com/
insteadOf = [email protected]:includeIf "gitdir:/path/to/work/": Applies work config to any repo under the specified directoryinsteadOf: Automatically rewrites both HTTPS and SSH URLs to use the correct SSH host- Per-directory configs: Ensures correct identity and SSH key for each account
- SSH URL rewriting:
[email protected]:gets rewritten to the appropriate SSH alias
With the insteadOf configuration, both HTTPS and SSH URLs automatically use the correct SSH key:
# Personal repositories (anywhere outside work directory)
git clone https://github.com/your-personal-username/awesome-project.git
# Automatically becomes: git@github-personal:your-personal-username/awesome-project.git
git clone [email protected]:your-personal-username/awesome-project.git
# Automatically becomes: git@github-personal:your-personal-username/awesome-project.git
# Work repositories (inside work directory)
cd /path/to/your/work/directory/
git clone https://github.com/your-company/company-project.git
# Automatically becomes: git@github-work:your-company/company-project.git
git clone [email protected]:your-company/company-project.git
# Automatically becomes: git@github-work:your-company/company-project.gitIf you prefer explicit SSH hosts, you can still use them directly:
# Personal repository
git clone git@github-personal:your-personal-username/repo.git
# Work repository
git clone git@github-work:your-company/repo.gitVerify your setup works correctly:
# 1. SSH connections
ssh -T github-personal # Should show personal username
ssh -T github-work # Should show work username
# 2. Git identity (outside work directory)
git config user.name # Should show personal name
git config user.email # Should show personal email
# 3. Git identity (inside work directory)
cd /path/to/your/work/directory/
git config user.name # Should show work name
git config user.email # Should show work email
# 4. URL rewriting (HTTPS)
git clone https://github.com/org/repo.git # Should use correct SSH host
# 5. URL rewriting (SSH)
git clone [email protected]:org/repo.git # Should use correct SSH host
# 6. Verify URL rewriting
git remote add origin [email protected]:org/repo.git
git remote -v # Should show the rewritten SSH alias URL- Work keys: Rotate every 6-12 months
- Personal keys: Rotate annually or when compromised
- Process: Generate new key → Add to GitHub → Update SSH config → Remove old key from GitHub
- Passphrases: Use strong passphrases for work keys
- Hardware tokens: Consider FIDO2 keys for maximum security
- Access control: Be mindful of which repositories you're accessing with which account
- Agent forwarding: Avoid forwarding SSH agents to untrusted hosts
Problem: Both ssh -T github-personal and ssh -T github-work show the same username.
Solution: Ensure IdentitiesOnly yes is set in your SSH config. This prevents SSH from trying other keys in the agent first.
Problem: Getting "Permission denied (publickey)" errors.
Solutions:
- Verify the SSH key was added to the correct GitHub account
- Check that the key file path in SSH config is correct
- Ensure proper permissions:
chmod 600 ~/.ssh/id_ed25519_github_*
Problem: Commits show wrong name/email.
Solution: Check your Git config and ensure includeIf is working:
git config --list --show-origin | grep userProblem: HTTPS URLs not converting to SSH.
Solution: Verify insteadOf rules in your Git config:
git config --get-regexp url- Accidental cross-use: Committing to work repos with personal identity (or vice versa)
- Key collisions: Misconfigured SSH hosts causing wrong key to be offered
- Agent exposure: SSH agent forwarding exposing wrong key to remote hosts
- Strict separation: Use clear hostnames (
github-personal,github-work) - Per-directory configs: Use
includeIffor automatic identity switching - Unambiguous naming: Name key files clearly to avoid confusion
- Regular testing: Use the test matrix to verify correct behavior
✅ Zero configuration per repository - works automatically
✅ No password prompts for Git operations
✅ Works with standard Git URLs - no special syntax to remember
✅ Automatic identity switching based on working directory
✅ Proper key isolation - each account uses its own SSH key
✅ Portable configuration - works across different machines
✅ Security best practices - proper permissions and key management
✅ Developer-friendly - just use normal Git commands anywhere
After setup, your configuration should look like:
~/.ssh/
├── id_ed25519_github_personal # Personal private key
├── id_ed25519_github_personal.pub # Personal public key
├── id_ed25519_github_work # Work private key
├── id_ed25519_github_work.pub # Work public key
└── config # SSH configuration
~/
├── .gitconfig # Global Git config
└── .gitconfig-work # Work-specific Git config
This setup provides a clean, secure, and developer-friendly way to manage multiple GitHub accounts on a single machine using Git's built-in features.