Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save edwhad/a25f728e6add3f6d1f7a483810e9d555 to your computer and use it in GitHub Desktop.
Save edwhad/a25f728e6add3f6d1f7a483810e9d555 to your computer and use it in GitHub Desktop.
How I configure multiple GitHub accounts using the 1password SSH agent (and working in WSL!)

How I use 1Password to manage SSH keys for multiple GitHub accounts (including on WSL)

If you don't care about why or how this works, you can skip right down to Setup Steps

A little bit of background

These are the considerations I tried to satisfy while researching this solution:

  1. I prefer not to generate new SSH keys for every machine/VM/environment where I use git or SSH. I end up with tons of keys per GitHub account or remote server, and I don't remember which is which.
  2. I want to keep private keys secured somewhere that is not directly accessible on the filesystem. Also try to avoid copying private keys around at all costs.
  3. I like the idea of having finer grained control over which applications are using the SSH keys per instance.
  4. I need to be able to use multiple GitHub accounts on the same instance without too much fuss.

After researching for quite a bit, I found that 1Password satisfied the top three requrements without having to carry around a hardware security key.

The most common solution I saw for point four is to edit your SSH config to give different names to the hosts associated with each of the accounts. I'm not a fan of this for a couple reasons:

  1. I don't like having to remember to set the remote url for all the repos for different credentials. I'll forget and it's kind of a pain to remember when cloning.
  2. When using the 1Password SSH agent in WSL, the WSL SSH config file isn't used, so this really isn't an option. You could set this all up in the Windows SSH config, but see point 1.

My Approach

My approach here is to use git config includes to make additional gitconfig files per 'account-directory' that specify exactly the keys (and account information) I want to use for the repos inside. I do this by overriding the SSH command to include the specific puclic key to use for that account - no ssh-agent retries or host configuration needed!

The only caveat is all repos associated with a GitHub account must live under a common parent directory, and not anywhere else on the filesystem.

In my case I have a folder structure like this:

~/src/
    /work/
        /work_repo1/
        /work_repo2/
        …
    /personal/
        /personal_repo1/
        /personal_repo2/
        …

The example above only shows two accounts, but technically there shouldn't be a limit to the amount of accounts you can use with this method. Since we're explicitly defining the key for each account (and assuming everything is configured correctly) you don't need to worry about the SSH server six key limit, since we'll be getting it right on the first try

Private Keys Stay in your Vault

When using the 1Password SSH agent you only need to export the public keys for each account to your filesystem, the private keys stay safe in the vault! The 1Password SSH agent will associate the public key to the correct private key in the vault at each time of use, so the private keys never need to leave your vault and aren't exposed.

Implementing in WSL

The approach up until this point is system agnostic. With this, you can have multiple GitHub accounts with separate SSH keys on any system (MacOS, Linux, Windows, etc..) There is just a bit of extra setup needed when implementing this on WSL

We need this extra step because the 1Password SSH agent isn't actually running under WSL at all. We use the host machine's Windows SSH tools for all SSH functionality. The additional setup is simply to alias your SSH commands to use the Windows ssh.exe (and optionally alias the op.exe if you want to use the CLI in WSL)


Setup Steps

1. Setup your 1Password experience on Windows

2. Make sure your Windows executables are available in WSL

  • In WSL run ssh.exe -V and make sure you get the OpenSSH_for_windows version.
  • If using the CLI check that op.exe --version works as well

3. Export your public keys to your WSL filesystem

  • In WSL:
  • If using the CLI run op.exe read 'op://<VAULT>/<personal_key_name>/public key' > ~/.ssh/<personal_key_name>.pub
  • If not, just export your key and copy it to you WSL filesystem in the ~/.ssh/ directory.
  • Repeat this step for all keys you want to use in WSL.

4. In WSL - Set up your .gitconfig files to use the correct keys per account.

  • Inside each directory that will contain repos from a GitHub account, create a new .gitconfig which defines the SSH command and key to use. So for a ~/src/personal/ directory create a ~/src/personal/.gitconfig file that contains

      [user]
              email = <personal_GitHub_email>
              name = <personal_GitHub_name>
      
      [core]
          sshCommand = ssh.exe -i /home/<WSL_user>/.ssh/<personal_key_name>.pub
    

            * Note: on systems other than WSL, simply replace ssh.exe with the SSH utility for that system, and keep the rest

  • Tell your main gitconfig to include this new gitconfig. In your ~/.gitconfig file add the following for the account-directory

      [includeIf "gitdir:~/src/personal/"]
          path = ~/src/personal/.gitconfig
    
  • I'd also recommend taking any account-specific information out of your main ~/.gitconfig file so if a repo ends up in a different directory, you'll be prompted for account information and know you need to update your configuration.

  • Any settings in the main gitconfig will carryover if they're not defined in the account-directory gitconfigs.

5. Repeat for each GitHub account-directory

  • When you're done you should have a folder structure similar this:

      ~/
          .gitconfig
          /src/
              /work/
                  .gitconfig
                  /work_repo1/
                  /work_repo2/
                  …
              /personal/
                  .gitconfig
                  /personal_repo1/
                  /personal_repo2/
                  …
    
  • Everything in git should work as normal!

  • When you pull/push/clone or do anything else that requires authentication, the Windows 1Password SSH agent will prompt you for authentication for the associated keys, and you can just authenticate in 1Password the way you normally do!

6. Commit signing

If you want commit signing for an account-directory, just follow the regular 1Password commit signing instructions for WSL, and make sure you put the signing information into the gitconfig for the associated account-directory (not the main ~/.gitconfig.)

Notes

Vaults

By default, the 1Password SSH agent will only include SSH keys that are stored in your default vaults (i.e. Personal, Private, or Employee Vault). If you move any SSH keys to a vault other than these three, you will need to explicity tell the SSH agent to include keys in that vault. This can be done by creating/editing the 1Password SSH agent config file.

Other Tools

I've only tested VSCode in WSL, but since we've configured the identities at the git and SSH level, any tools that are defined as compatible with the 1Password SSH agent should work properly.

Using SSH outside of Git in WSL.

Sure that's all fine and dandy for git, but if you want to use the 1Password SSH agent in WSL for authenticating connections to any SSH servers, you just need to add an SSH alias to the shell profile/rc file!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment