The most recent version of 1Password from Agilebits had added some great new features, and one I particularly love is SSH Keys. By establishing 1Password as your SSH Key Agent, you can let it store (or generate!) ssh keys and synchronize them across multiple devices, just like passwords. With this, I’m finally able to have a single SSH key setup for accessing my various Github and raspberry PI devices, without having to manage a separate key per device. It also means I can authenticate my SSH keys via whatever biometrics the local device supports (on Macs that TouchID ,on Windows that’s Windows Hello).
However, there’s one big problem that it seems everyone using SSH keys runs into when doing development: GitHub.
Git, and Github, supports (and recommends) using SSH Keys for authentication. Not only are they safer, but SSH is typically faster than HTTPS due to the various compression that SSH adds in. I won’t get into the details of how to set it up, there are plenty of other guides for that.
The problem is one of security:
- GitHub authenticates all SSH connections as the user
- GitHub identifies the specific user via their SSH key
- GitHub only allows an SSH key to be used by a single account (because it’s not only authentication but identification)
For people working in Mac or Linux, that usually means cryptic
.ssh/configfiles where they define multiple virtual hostnames that select a specific key, then rewriting their git origin URL’s from
personalgit:repo.git. Again, lots of guides online.
When you’re on a windows computer, you run into this same problem. Some tools like GitHub Desktop have built-in ways around this, but if you want to use the commandline git tools integrated with things like Sublime Text or VSCode, you have to find a more generic solution.
Looking in the 1Password documentation, you might immediately be disheartened to see this:
Windows doesn't have the same flexibility as macOS and Linux when it comes to the
~/.ssh/configfile. This is because the
\\.\pipe\openssh-ssh-agentpipe that Microsoft OpenSSH listens to is fixed. If you want to use the 1Password SSH agent on Windows, you'll need to allow it to authenticate for all hosts.
I tried a few things and didn’t get very far. I reached out to 1Password support on twitter and via email and initially got some rather disheartening news:
I am sorry to say that Windows does not have the option to use 1Password Agent for multiple hosts like Mac and Linux, so if you want to use different keys on Windows, we will need to remove 1Password as the global agent and add your private keys to the config file.
Well that seemed pretty short-sighted from a company like AgileBits (creator of 1Password). Thankfully, they escalated it internally and a higher-level engineer reached out with a solution.
The solution is basically the same as for Mac & Linux, just with some Windows flavor added.
- First, you have to export the Public key from your github keys and save them in your personal folder.
To do this, download your public key for the first account from the 1Password desktop app using the down arrow on the public key field. Rename it to
personal.pubas necessary, and repeat with the other key. Put both public keys in the
.sshfolder in your Windows user account directory found at
- After saving both public keys to the
.sshfolder, edit the
configfile in the
.sshfolder, and build a configuration like so:
For your work GitHub account, create a host entry as follows:
Host workgit HostName github.com User git IdentityFile ~/.ssh/work.pub IdentitiesOnly yesFor your personal GitHub account, create a host entry like this:
Host personalgit HostName github.com User git IdentityFile ~/.ssh/personal.pub IdentitiesOnly yes
- At this point, if everything is functioning properly, you should be able to do
ssh personalgitand, despite SSH throwing an error and immediately dumping you back to a prompt, see a message from Github recognizing your username. Similarly, if you
ssh workgityou’ll see it recognize the other account.
- This is the part that is tricky. By default, git on windows includes its own internal SSH that doesn’t recognize this setup. To make it use the OpenSSH version that interfaces with 1Password, you need to do the following:
git config --global core.sshCommand "C:\\Windows\\System32\\OpenSSH\\ssh.exe"
Once that’s done, you should be good to rewrite your individual repo remotes. That can be done through something like one of the two commands below:
git remote set-url origin set-url personalgit:<Username>/<reponame>.git git remote set-url origin set-url workgit:<Username>/<reponame>.git
After using this for a few days, I can say it works great! Now I can directly push code from inside VSCode or via commandline, and on my Windows Laptop I get a quick Windows Hello PIN verification and it’s done!
It’s a bit annoying to have to mentally modify the URL’s every time I want to clone a new repo, however. The built-in dropdown visible in github still shows
email@example.com the beginning of every SSH clone, and I have to rewrite it over to the appropriate account if I want things to function properly (Usually I can clone without issue, it’s just if I ever want to submit back).
Hope you find this helpful!