Two GitHub Accounts on a Mac, the Simple Way

October 11, 2025 (1w ago)

Keeping personal and work code separate is healthy for your mind and your repos. This guide shows a simple way to use two GitHub accounts on one Mac. You will have two folders, one for work and one for personal. Git will pick the right identity for you based on where you are.

What You'll Learn

Prerequisites

Table of Contents

  1. Create folders and prepare SSH directory
  2. Create SSH keys for each account
  3. Add public keys to GitHub accounts
  4. Configure SSH client
  5. Create per-scope Git configurations
  6. Set up conditional Git config includes
  7. Clean up global Git settings
  8. Test the setup
  9. Troubleshooting
  10. One-shot installer
  11. Health check script

Replace placeholders like <WORK_EMAIL>, <PERSONAL_EMAIL>, and <YOUR_MACOS_USERNAME> with your values.


What you will create

Files that will be created or updated:

Folder layout on disk:

/Users/<YOUR_MACOS_USERNAME>/developer/work/      # work repos
/Users/<YOUR_MACOS_USERNAME>/developer/personal/  # personal repos

Step 1: Create folders and prepare ~/.ssh

Time estimate: 1 minute

Why this works: We create separate directories for work and personal repositories, and ensure the SSH directory has proper permissions for security.

mkdir -p /Users/<YOUR_MACOS_USERNAME>/developer/work /Users/<YOUR_MACOS_USERNAME>/developer/personal ~/.ssh
chmod 700 ~/.ssh

Verification:

ls -la ~/.ssh  # Should show drwx------ permissions
ls -ld /Users/<YOUR_MACOS_USERNAME>/developer/work /Users/<YOUR_MACOS_USERNAME>/developer/personal  # Should show directories exist

Step 2: Create one SSH key for each account

Time estimate: 3 minutes

Why this works: Each GitHub account needs its own SSH key pair. ED25519 keys are more secure and efficient than RSA keys. The SSH agent manages these keys and macOS Keychain integration provides seamless authentication.

# Work key
ssh-keygen -t ed25519 -C "<WORK_EMAIL>" -f ~/.ssh/id_ed25519_work
 
# Personal key
ssh-keygen -t ed25519 -C "<PERSONAL_EMAIL>" -f ~/.ssh/id_ed25519_personal
 
# Start SSH agent and load keys into macOS Keychain
# Note: eval "$(ssh-agent -s)" starts the SSH agent in the current shell
# The --apple-use-keychain flag stores keys in macOS Keychain for persistence
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_personal
 
# Set secure permissions
chmod 600 ~/.ssh/id_ed25519_work ~/.ssh/id_ed25519_personal
chmod 644 ~/.ssh/id_ed25519_work.pub ~/.ssh/id_ed25519_personal.pub

Note: When prompted for a passphrase, you can either:

Verification:

ssh-add -l  # Should list both keys
ls -la ~/.ssh/id_ed25519_*  # Should show both key pairs with correct permissions

Step 3: Add the public keys to the right GitHub accounts

Time estimate: 2 minutes

Why this works: GitHub needs your public key to verify that you own the corresponding private key. Each account gets its own public key, ensuring proper authentication.

Copy each key then add it in GitHub settings under SSH and GPG keys.

pbcopy < ~/.ssh/id_ed25519_work.pub         # paste into your WORK GitHub account
pbcopy < ~/.ssh/id_ed25519_personal.pub     # paste into your PERSONAL GitHub account

Keyboard shortcut: Cmd+C copies selected text, Cmd+V pastes

Use clear titles like work-mac and personal-mac.

Verification: After adding keys to GitHub, test the connection:

ssh -T git@github.com  # Should work with your default account

Step 4: Create or edit ~/.ssh/config

Time estimate: 2 minutes

Why this works: SSH config allows us to create aliases for GitHub that use different keys. The IdentitiesOnly yes directive ensures SSH only tries the specified key, preventing authentication confusion.

This picks the correct key for each account.

File: ~/.ssh/config

Host *
  AddKeysToAgent yes
  UseKeychain yes
 
Host github.com-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
  IdentitiesOnly yes
 
Host github.com-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes

Verification:

ssh -T git@github.com-personal    # should greet your personal username
ssh -T git@github.com-work        # should greet your work username

Step 5: Create per scope Git configs

Time estimate: 3 minutes

Why this works: These per scope files make Git use the right identity and key based on the folder you are in. They set user.name and user.email for each scope so commits always carry the correct email, and they add url.insteadOf rules that rewrite normal GitHub URLs to the matching SSH host alias. That means you can keep using plain github.com clone URLs and Git will quietly choose the correct SSH key without prompts or special hostnames.

The url.insteadOf rules are the magic that makes this seamless - they automatically rewrite URLs so you don't need to remember special hostnames.

File: ~/.gitconfig-work

[user]
    name = Your Name (Work)
    email = <WORK_EMAIL>
 
[url "git@github.com-work:"]
    insteadOf = git@github.com:
[url "ssh://git@github.com-work/"]
    insteadOf = ssh://git@github.com/
[url "git@github.com-work:"]
    insteadOf = https://github.com/

File: ~/.gitconfig-personal

[user]
    name = Your Name (Personal)
    email = <PERSONAL_EMAIL>
 
[url "git@github.com-personal:"]
    insteadOf = git@github.com:
[url "ssh://git@github.com-personal/"]
    insteadOf = ssh://git@github.com/
[url "git@github.com-personal:"]
    insteadOf = https://github.com/

Verification:

# Test URL rewriting
cd /tmp && git init test-repo
cd test-repo
echo '[url "git@github.com-work:"]
    insteadOf = git@github.com:' > .git/config
git remote add origin git@github.com:test/test.git
git config --get remote.origin.url  # Should show git@github.com-work:test/test.git

Step 6: Teach Git to include the right config by folder

Time estimate: 2 minutes

Why this works: Git's includeIf directive allows conditional configuration based on the current working directory. This is what makes Git automatically switch identities based on which folder you're in.

Use absolute paths and keep the trailing slashes.

File: ~/.gitconfig Append these lines:

[includeIf "gitdir:/Users/<YOUR_MACOS_USERNAME>/developer/work/"]
    path = ~/.gitconfig-work
 
[includeIf "gitdir:/Users/<YOUR_MACOS_USERNAME>/developer/personal/"]
    path = ~/.gitconfig-personal

If ~/.gitconfig did not exist, you can create it with only those lines.

Verification:

# Test in work directory
cd /Users/<YOUR_MACOS_USERNAME>/developer/work
git config --show-origin --get user.email  # Should show work email
 
# Test in personal directory
cd /Users/<YOUR_MACOS_USERNAME>/developer/personal
git config --show-origin --get user.email  # Should show personal email

Step 7: Remove any old global identity

Time estimate: 1 minute

Why this works: Removing global Git identity prevents conflicts and ensures that only the folder-specific identities are used. This avoids confusion during verification.

This avoids confusion during checks later.

git config --global --unset user.name  || true
git config --global --unset user.email || true

Verification:

git config --global --get user.name   # Should return nothing
git config --global --get user.email  # Should return nothing

Step 8: Use it in daily work

Time estimate: Ongoing

Why this works: Now everything is set up! Git automatically detects which folder you're in and applies the correct identity and SSH key. You can use normal GitHub URLs everywhere.

Use normal GitHub URLs. Git switches identity for you based on folder.

# Work
cd /Users/<YOUR_MACOS_USERNAME>/developer/work
git clone git@github.com:<YOUR_WORK_ORG>/<your-work-repo>.git
cd <your-work-repo>
git config --show-origin --get user.email   # shows <WORK_EMAIL>
 
# Personal
cd /Users/<YOUR_MACOS_USERNAME>/developer/personal
git clone git@github.com:<YOUR_PERSONAL_USERNAME>/<your-personal-repo>.git
cd <your-personal-repo>
git config --show-origin --get user.email   # shows <PERSONAL_EMAIL>

Keyboard shortcuts:


Troubleshooting quick checks

Permission denied (publickey)

Symptoms: SSH authentication fails with "Permission denied (publickey)"

Solutions:

# Check if keys are loaded
ssh-add -l
 
# Reload keys if needed
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_personal
 
# Fix permissions
chmod 700 ~/.ssh && chmod 600 ~/.ssh/* && chmod 644 ~/.ssh/*.pub

Make sure the ~/.ssh/config host blocks exist and have IdentitiesOnly yes.

Includes not triggering

Symptoms: Git uses wrong identity or doesn't switch identities

Solutions:

# Check current identity
cd /path/to/your/repo
git config --show-origin --get user.email
 
# Verify includeIf paths
cat ~/.gitconfig | grep -A2 includeIf

Confirm the gitdir: paths in ~/.gitconfig are absolute and end with a slash. Check that the repo is actually inside the target folder.

HTTPS prompts

Symptoms: Git asks for username/password instead of using SSH

Solutions: Your scoped configs rewrite https://github.com/ to SSH. If a remote still uses HTTPS, run:

git remote set-url origin "$(git remote get-url origin | sed 's#https://github.com/#git@github.com:#')"

macOS Version Considerations

Alternative Methods

Method 1: Using Git Credential Manager

# Install Git Credential Manager
brew install --cask git-credential-manager-core
 
# Configure for multiple accounts
git config --global credential.helper manager-core

Method 2: Using SSH Agent with different ports

# Start SSH agent on different port
ssh-agent -a /tmp/ssh-agent-work
ssh-agent -a /tmp/ssh-agent-personal

One shot installer

Time estimate: 2 minutes

Why this works: This script automates all the manual steps above. It's idempotent (safe to run multiple times) and handles edge cases like existing keys and configs.

If you prefer a single script, copy this into Terminal, then add the printed keys in GitHub.

# Your details
PERSONAL_EMAIL="<PERSONAL_EMAIL>"
WORK_EMAIL="<WORK_EMAIL>"
WORKDIR="/Users/<YOUR_MACOS_USERNAME>/developer/work/"
PERSONALDIR="/Users/<YOUR_MACOS_USERNAME>/developer/personal/"
 
set -e
 
mkdir -p "$WORKDIR" "$PERSONALDIR" ~/.ssh
chmod 700 ~/.ssh
 
# Create keys if missing
[[ -f ~/.ssh/id_ed25519_work ]] || ssh-keygen -t ed25519 -C "$WORK_EMAIL" -f ~/.ssh/id_ed25519_work -N ""
[[ -f ~/.ssh/id_ed25519_personal ]] || ssh-keygen -t ed25519 -C "$PERSONAL_EMAIL" -f ~/.ssh/id_ed25519_personal -N ""
 
# Start agent and add keys
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_work
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_personal
 
# Permissions
chmod 600 ~/.ssh/id_ed25519_work ~/.ssh/id_ed25519_personal 2>/dev/null || true
chmod 644 ~/.ssh/id_ed25519_work.pub ~/.ssh/id_ed25519_personal.pub 2>/dev/null || true
 
# ~/.ssh/config
cat > ~/.ssh/config <<'EOF'
Host *
  AddKeysToAgent yes
  UseKeychain yes
 
Host github.com-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
  IdentitiesOnly yes
 
Host github.com-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
 
# ~/.gitconfig-work
cat > ~/.gitconfig-work <<EOF
[user]
    name = Your Name (Work)
    email = $WORK_EMAIL
[url "git@github.com-work:"]
    insteadOf = git@github.com:
[url "ssh://git@github.com-work/"]
    insteadOf = ssh://git@github.com/
[url "git@github.com-work:"]
    insteadOf = https://github.com/
EOF
 
# ~/.gitconfig-personal
cat > ~/.gitconfig-personal <<EOF
[user]
    name = Your Name (Personal)
    email = $PERSONAL_EMAIL
[url "git@github.com-personal:"]
    insteadOf = git@github.com:
[url "ssh://git@github.com-personal/"]
    insteadOf = ssh://git@github.com/
[url "git@github.com-personal:"]
    insteadOf = https://github.com/
EOF
 
# Ensure ~/.gitconfig exists
touch ~/.gitconfig
 
# Remove old includeIf blocks for these dirs
sed -i '' '/\[includeIf "gitdir:.*developer\/work\/"\]/{N;N;d;}' ~/.gitconfig 2>/dev/null || true
sed -i '' '/\[includeIf "gitdir:.*developer\/personal\/"\]/{N;N;d;}' ~/.gitconfig 2>/dev/null || true
 
# Append correct includeIf blocks
{
  echo
  echo "[includeIf \"gitdir:${WORKDIR}\"]"
  echo "    path = ~/.gitconfig-work"
  echo
  echo "[includeIf \"gitdir:${PERSONALDIR}\"]"
  echo "    path = ~/.gitconfig-personal"
} >> ~/.gitconfig
 
echo "-----------------------------------------"
echo "Done. Add these public keys in GitHub settings."
echo
echo "WORK key:"
cat ~/.ssh/id_ed25519_work.pub
echo
echo "PERSONAL key:"
cat ~/.ssh/id_ed25519_personal.pub
echo "-----------------------------------------"
echo "Then test:"
echo "ssh -T git@github.com-work"
echo "ssh -T git@github.com-personal"

Quick health check

Time estimate: 1 minute

Why this works: This diagnostic script checks all components of your setup and provides a comprehensive status report. It's useful for troubleshooting and verifying everything is working correctly.

This script gives you a short status readout.

cat <<'CHK' > /tmp/git-ssh-healthcheck.sh
#!/usr/bin/env bash
set -e
echo "SSH agent keys:"
ssh-add -l || true
echo
echo "~/.ssh/config hosts:"
grep -E 'Host github.com-(personal|work)' -n ~/.ssh/config || true
echo
echo "Git includes and identities:"
git config --list --show-origin | grep -E 'includeIf|user.name|user.email' || true
echo
echo "Testing SSH identities:"
ssh -T git@github.com-work || true
ssh -T git@github.com-personal || true
CHK
bash /tmp/git-ssh-healthcheck.sh

Conclusion

That's it! You now have a robust setup for managing two GitHub accounts on a Mac. Here's what you've accomplished:

Put work repos in the work folder and personal repos in the personal folder. Use normal GitHub URLs. Git will pick the right identity for you.

Next Steps