From Passwords to Keys: Setting Up GitHub SSH Authentication on macOS (and Never Typing Credentials Again)
If you are still cloning GitHub repositories over HTTPS and repeatedly authenticating with browser logins or tokens, switching to SSH is one of those small infrastructure improvements that pays off every day.
SSH authentication gives you:
- Passwordless Git operations after initial setup
- Separate identities for personal and work GitHub accounts
- Better compatibility with terminal-first workflows
- Secure private-key authentication without storing access tokens in remotes
- Seamless operation across tools such as VS Code, Cursor, Claude Code, terminal Git, CI tooling, and developer containers
This guide walks through generating SSH keys, configuring GitHub, setting up macOS keychain integration, and migrating existing repositories.
For a setup with both personal and work GitHub accounts, we will configure separate identities and make SSH automatic.
Why SSH Instead of HTTPS?
Git supports multiple authentication methods.
| Method | Pros | Cons |
|---|---|---|
| HTTPS + browser login | Simple initially | Frequent prompts, token management |
| HTTPS + PAT | Works everywhere | Token storage overhead |
| SSH | Fast, secure, transparent | Initial setup required |
Once configured correctly, SSH becomes nearly invisible.
You simply run:
git pull
git push
git clone
…and authentication just happens.
Step 1 – Generate SSH Keys
Open Terminal.
Generate one key for personal projects:
ssh-keygen -t ed25519 -f ~/.ssh/github -C "me@personal.com"
Generate another for work:
ssh-keygen -t ed25519 -f ~/.ssh/github-work -C "me@work.com"
Why ed25519?
ed25519 is the modern recommendation for SSH keys because it provides:
- Strong security
- Fast authentication
- Smaller key size
- Wide support
When prompted:
Enter passphrase:
Adding a passphrase is recommended.
After completion:
~/.ssh/github
~/.ssh/github.pub
~/.ssh/github-work
~/.ssh/github-work.pub
Private keys stay local.
Only .pub files are uploaded to GitHub.
Step 2 – Add Keys to the macOS SSH Agent
The SSH agent keeps your decrypted key available so you do not need to enter the passphrase repeatedly.
Check existing identities:
ssh-add -l
Add your keys:
ssh-add --apple-use-keychain ~/.ssh/github
ssh-add --apple-use-keychain ~/.ssh/github-work
macOS stores passphrases securely in Keychain.
Verify:
ssh-add -l
Expected output:
256 SHA256:...
Step 3 – Configure ~/.ssh/config
This is the most important step.
Create:
nano ~/.ssh/config
Add:
Host github.com
IdentityFile ~/.ssh/github
HostName github.com
User git
AddKeysToAgent yes
UseKeychain yes
IdentitiesOnly yes
Host github.com-work
IdentityFile ~/.ssh/github-work
HostName github.com
User git
AddKeysToAgent yes
UseKeychain yes
IdentitiesOnly yes
Save.
This configuration means:
Personal account
git@github.com:user/repo.git
uses:
~/.ssh/github
Work account
git@github.com-work:company/repo.git
uses:
~/.ssh/github-work
No manual switching required.
Step 4 – Copy the Public Keys
Copy personal:
cat ~/.ssh/github.pub | pbcopy
Copy work:
cat ~/.ssh/github-work.pub | pbcopy
The keys are now in your clipboard.
Step 5 – Add Keys to GitHub
Open:
GitHub SSH and GPG Keys Settings
For each key:
- Click New SSH key
- Choose a descriptive title:
- MacBook Pro
- MacBook Work
- Paste the public key
- Click Add SSH key
Repeat for both identities.
Step 6 – Test Authentication
Personal:
ssh -T git@github.com
Work:
ssh -T git@github.com-work
Expected:
Hi username! You've successfully authenticated...
If you see:
Permission denied (publickey)
verify:
ssh-add -l
cat ~/.ssh/config
Step 7 – Configure Git to Use the Correct Identity
Set your Git identity globally:
Personal:
git config --global user.name "Your Name"
git config --global user.email "me@personal.com"
For work repositories:
git config user.name "Your Work Name"
git config user.email "me@work.com"
You can place those values per repository.
Verify:
git config --list
Migrating Existing Repositories from HTTPS to SSH
Many developers already have dozens of repositories cloned via HTTPS.
Check current remote:
git config --get remote.origin.url
Example:
https://github.com/user/project.git
Convert manually:
git remote set-url origin git@github.com:user/project.git
Verify:
git remote -v
Automate Converting One Repository
Save as:
git_remote_to_ssh.sh
#!/bin/bash
set -euo pipefail
url=$(git config --get remote.origin.url)
if [[ ! "$url" =~ ^https:// ]]; then
echo "Error: remote URL does not start with https:// ($url)" >&2
exit 1
fi
new_url=$(echo "$url" | sed -E 's#^https://github\.com/#git@github.com:#')
git remote set-url origin "$new_url"
echo "origin: $url -> $new_url"
Make executable:
chmod +x git_remote_to_ssh.sh
Run inside a repository:
./git_remote_to_ssh.sh
Bulk Convert All Repositories in a Directory
If you keep many repositories under one folder:
~/src
~/repos
~/projects
Use this helper.
Save as:
convert_all_git_remotes.sh
#!/bin/bash
set -uo pipefail
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
target="$script_dir/git_remote_to_ssh.sh"
if [[ ! -x "$target" ]]; then
echo "Error: $target not found or not executable" >&2
exit 1
fi
base=$(pwd)
for dir in */; do
dir="${dir%/}"
if [[ -d "$dir/.git" ]]; then
echo "==> $dir"
(
cd "$dir"
"$target"
) || echo " (skipped: $dir)"
fi
done
cd "$base"
Make executable:
chmod +x convert_all_git_remotes.sh
Run:
./convert_all_git_remotes.sh
Every cloned GitHub repository under the current directory will be migrated automatically.
Optional: Clone New Repositories Using SSH by Default
Instead of:
git clone https://github.com/user/repo.git
Use:
git clone git@github.com:user/repo.git
For work:
git clone git@github.com-work:company/repo.git
Now every Git operation automatically uses your configured SSH identity.
Final Thoughts
SSH authentication is one of those developer quality-of-life improvements that disappears once configured correctly—which is exactly the point.
With:
- dedicated personal and work identities
- automatic Keychain integration
- persistent SSH agent configuration
- repository migration scripts
…Git authentication becomes invisible infrastructure instead of daily friction.
Set it up once and forget about it.
Discussion in the ATmosphere