Using different SSH Private Keys for specific Git repositories

Scenario

Managing multiple Git repositories across different platforms and user accounts can be a logistical nightmare. Juggling various private/public key combinations and juggling your identity for each project quickly becomes a headache.

For a long time, my primary solution was to rely on individual profiles within Git clients like GitKraken, assigning each profile its own private key. While this functioned, it felt clunky and lacked the set-and-forget way which I always prefer.

Luckily, I recently stumbled upon a brilliant approach that streamlines this multi-repository workflow. Eager to share this game-changer with you, let's dive in!

Option 1: Using SSH Config

Managing private and business-related GitHub repositories for example often involves juggling different SSH keys. Your system's SSH config file offers a powerful solution, allowing you to configure multiple hosts with their corresponding key identities for seamless authentication.

This guide demonstrates how to set up this functionality, using GitHub Business and GitHub Private accounts as examples.

1. Configure Your SSH File:

Open your SSH config file (located at ~/.ssh/config) and add the following entries, replacing id_rsa_business and id_rsa_private with your actual key file names:

Host github-business
    HostName github.com
    IdentityFile ~/.ssh/id_rsa_business

Host github-private
    HostName github.com
    IdentityFile ~/.ssh/id_rsa_private

2. Cloning with Defined Hosts:

With these hosts established, cloning repositories becomes a breeze. Simply adjust the hostname in the URL:

git clone git@github-business:example/repository.git

Your system automatically recognizes the defined host and connects to GitHub.com using the corresponding private key. Importantly, the modified URL is stored within your local Git repository, ensuring future commands work same way as the initial clone command.

By leveraging this approach, you only need to remember your configured host names and adjust the URLs accordingly.

Option 2: Configuration with core.sshCommand

For all of my development environments, I favor a more flexible approach using Git's configuration options. By using the git config command, we can define repository-specific settings without modifying system-wide SSH configurations.

By omitting the --global flag, changes are confined to the current repository's .git/config file. Let's revisit our previous case using two different accounts. During cloning, there's no need to alter the URL. Instead, execute the following command after cloning within the repository:

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_business"

Alternatively, you can pass this configuration directly during cloning:

git clone -c "core.sshCommand=ssh -i ~/.ssh/id_rsa_business" git@github.com:example/repository.git

This approach stores the configuration for future use within the repository itself. Personally, I prefer this method to avoid managing numerous host entries in my operating system's SSH file.

Furthermore, it allows customizing individual repositories, enabling you to assign distinct private keys in case a repository's structure evolves, like shifting from a private organization to a business account on GitHub. It also allows you to easily execute that command for existing repositories, which you already have stored for decades in your local development environment.

Conclusion: Tailoring Your Workflow

The choice between these options boils down to personal preference. Both options provide robust and flexible solutions for your development environment. Experimenting with each approach can help you identify the workflow that best aligns with your needs and coding style.