Two GitHub accounts (personal Cygnus0923, work your-work-account) on one Ubuntu machine, set up 2026-08-29. Prerequisite: ssh-keys-and-github (key generation, ssh-agent, adding keys, cloning); this note covers only the extra work for a second account.
The big picture
- GitHub identifies you by SSH key, not username. Two accounts = two keys, and SSH must pick the right one per repo.
- Left alone, SSH offers keys in order → you silently authenticate as the wrong person.
- Fix: one key per account + a host alias that pins exactly one key.
1. A separate key per account
ssh-keygen -t ed25519 -C "descriptive-label" -f ~/.ssh/id_ed25519_github_personal-t ed25519→ modern elliptic-curve, shorter and stronger than RSA (legacy).-C→ a label only, no functional effect. Name the machine (xuebin@Cygnus-2026-08-29), not your email: it tells you which key to revoke when several machines share an account.- Upload only the
.pubto GitHub → Settings → SSH and GPG keys. The file without.pubis the private key and never leaves the machine.
Overwrite prompt: there is no undo
ssh-keygenasks before overwriting an existing key. Never answerywithout knowing what that key is still used for.
2. Host aliases in ~/.ssh/config
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github_personal
IdentitiesOnly yes
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yeschmod 600 ~/.ssh/config # SSH may refuse a config others could writeIdentitiesOnly yesis the critical line. Without it SSH offers every key until one is accepted → you’re whichever account matches first. With it, each alias uses exactly one key.chmod 600matters: a writable config could silently redirect your keys.
3. Rewrite the clone URL to use the alias
The step that catches everyone
GitHub’s URL
[email protected]:Cygnus0923/notes-.gitmatches neither Host block, soIdentitiesOnlynever applies and SSH falls back to the default key. Rewrite the host part:github-personal:Cygnus0923/notes-.git.
git remote set-url origin github-personal:OWNER/REPO.git # fix an existing repo
git clone github-personal:OWNER/REPO.git # or clone correctly4. Per-repo git identity
git config --local user.name "Xuebin Nam"
git config --local user.email "[email protected]"
git config --global user.useConfigOnly true # safety net, set once- The SSH key controls access; the commit author is separate. If the email isn’t a verified address on that account, GitHub won’t attribute the commit to your profile.
useConfigOnly→ git refuses to commit in a repo with no identity set, instead of quietly inventing one from your hostname.
Use
--local, not--globalA global email silently leaks your personal address onto work commits in any repo where you forget to override it.
5. Verify
ssh -T github-personal # -> "Hi Cygnus0923!"
ssh -T github-work # -> "Hi your-work-account!"
git ls-remote origin # succeeds = remote reachable with the right keyTroubleshooting
| Symptom | Likely cause | Check / fix |
|---|---|---|
Repository not found (private repo) | repo doesn’t exist, or your key’s account can’t see it. GitHub says “not found” instead of “permission denied” so it doesn’t reveal which private repos exist | check which account you authenticated as (ssh -T github-personal) before assuming the repo is missing |
Related: git-daily-workflow