I have a personal GitHub account and a corporate one, and I found it annoying to have to select the correct SSH key for work repos, so I configured git and SSH to pick the correct key for me. After initial setup, there are three config files to modify:
After the initial setup, there are three config files involved:
- Git URL rewrite (`~/.gitconfig`) — rewrites work org URLs to an SSH host alias
- SSH host alias (`~/.ssh/config`) — maps that alias to the right key (and port 443 if needed)
- Work-only Git identity (`~/.gitconfig.work`) — sets work email/name/signing key, loaded automatically for work repos
The mental model is:
- Git rewrites
git@github.com:my-org/...→git@github.com-work:my-org/... - SSH sees
github.com-workand uses the work SSH key (and optional port443) - Git config loads your work identity/signing settings only when the repo is a work repo
I clone a work repo now and everything is already correct.
Generating the keys
SSH key first:
ssh-keygen -t ed25519 -C "you@work.com" -f ~/.ssh/work_id_ed25519
Give it a passphrase, then add the public key (~/.ssh/work_id_ed25519.pub) to your work GitHub account under Settings > SSH and GPG keys.
(Optional if you want commit signing) GPG key:
brew install gnupg # if not installed
gpg --full-generate-key
Pick RSA 4096 or ed25519, enter work email. Then grab the key ID:
gpg --list-secret-keys --keyid-format long
The hex string after the algorithm (e.g.ed25519/94DC844444530B75) is your signing key ID. Add the public key to GitHub too:
gpg --armor --export 94DC844444530B75
Paste that into Settings > SSH and GPG keys > New GPG key.
Git URL rewrite (~/.gitconfig)
Configure Git to map the work github host to a pseudo-hostname (a “hook” that SSH can match on):
[url "git@github.com-work:my-org/"]
insteadOf = git@github.com:my-org/
Now whenever I clone, push etc. to a repo under my work org, git transparently rewrites the host to the pseudo-hostname.
SSH host alias (~/.ssh/config)
SSH resolves github.com-work here and connects to GitHub’s SSH-over-HTTPS endpoint with my work key.
Host github.com-work
HostName ssh.github.com
Port 443
IdentityFile ~/.ssh/work_id_ed25519
IdentitiesOnly yes
IdentitiesOnlyyes stops the agent from trying my personal key.- It uses port
443because corporate the firewall blocks22.
Quickly check SSH config works:
❯ ssh -T git@github.com-work
Hi your-work-github-username! You've successfully authenticated, but GitHub does not provide shell access.
Configure work-specific git config
Create ~/.gitconfig.work with work identity:
[user]
email = you@work.com
name = Your Name
signingkey = YOUR_GPG_KEY_ID
[github]
user = your-work-github-username
[commit]
# if you want signed commits
gpgsign = true
Hook it up with includeIf so it auto-loads
This tells Git when to include the work config. Because the URL rewrite above changes work remotes to git@github.com-work:my-org/..., you can include your work identity only when a repo has a remote URL matching that pattern:
# ~/.gitconfig
[includeIf "hasconfig:remote.*.url:git@github.com-work:my-org/"]
path = ~/.gitconfig.work
That tells Git: if any remote URL in this repo matches git@github.com-work:my-org/..., load ~/.gitconfig.work to set my work email/name/signing key.
All three files are templates gated on a machineRole variable in Chezmoi, which gets set during chezmoi init. On a personal machine, none of this renders.
I clone a work repo now and everything is already correct and i haven’t thought about it since setting it up.