DEV Community

JT Ziolo
JT Ziolo

Posted on

Quickly and Easily Manage Multiple SSH and GPG Keys Across Git Repositories

Git relies on SSH and GPG to ensure secure and authenticated interactions with remote repositories. However, if you use multiple SSH and GPG identities and aren't careful while configuring Git, you can encounter specific issues when running Git commands. I've arrived at the following solution for these issues that I wanted to share since it may work well for others.

First, a disclaimer: this approach is not intended to replace full-featured identity management tools, and some customization may be required for more complex use cases (e.g., short-lived SSH or GPG keys), but I feel this can be helpful for some developers out there.

Understanding SSH and GPG in Git

SSH (Secure Shell) ensures secure communication between your local machine and remote Git repositories. When used with Git, it allows for encrypted data transfer and authentication, making it the preferred choice for interacting with popular hosting platforms like GitHub, GitLab, and Bitbucket 1.

GPG (GNU Privacy Guard) can be used to digitally sign and verify Git commits. By signing their commits, developers prove their authorship over each commit and combat the threat of commit spoofing. Most version control providers support GPG signatures and offer mechanisms to verify signed commits 1 2 3.

The Pitfalls of Global SSH and GPG Settings

While global SSH and GPG settings can be convenient, relying solely on them can lead to complications, especially when managing multiple identities 1:

  1. SSH Key Confusion: When multiple SSH keys are configured globally, SSH may attempt to use the wrong key for authentication, resulting in failed login attempts. If authentication fails (e.g., because you mistyped the password), the agent cycles through each key to find a working one, which can be confusing and frustrating.

  2. GPG Signing Errors: If you have multiple GPG keys, Git might use the incorrect key for signing, leading to verification failures when pushing commits.

  3. Configuration Conflicts: Setting the wrong GPG or SSH key in your global Git configuration can cause signing failures across all repositories.

Checking the Git Identity with Bash

Before we continue, I'll assume you have already set up Git to require GPG-signed commits globally (this is controlled by the commit.gpgsign setting) 4.

Under normal circumstances, it can be challenging to determine which SSH key Git will use for fetch, pull, and push commands. To get around this, we'll force Git to use a specific SSH key file using the core.sshCommand setting. Here's an example of how you might change this setting from the command line:

git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_johndoe_work -o IdentitiesOnly=yes"
Enter fullscreen mode Exit fullscreen mode

Assuming that we have forced Git to use a specific SSH key file, we can quickly check which SSH and GPG keys Git will use with the following (barebones) Bash function. Feel free to edit it to produce neater output.

function git-check() {
    git config core.sshCommand
    git config user.name
    git config user.email
    git config user.signingkey
}
Enter fullscreen mode Exit fullscreen mode

Add the function to your ~/.bashrc or ~/.bash_profile file, and source the file using source ~/.bashrc. You should now be able to navigate to a Git repo on your machine and run git-check to determine the identity that Git will use for the Git commands you run in that repo.

Security Considerations

The information we'll be working with is (in many cases) not as sensitive as you might think.

  • The filepath to the SSH file doesn't expose the key itself.
  • The user name and email settings contain public information for each git commit.
  • The GPG signing key fingerprint identifies the public key, and isn't sensitive.

We can prove that the GPG signing key used by Git isn't sensitive with a quick exercise. Go to GitHub and find a popular repo that has GPG-signed commits. If you click the "Verified" badge next to a commit, you'll see a message that includes the GPG key ID. This is the same value as the signing key that we will be using in our Git configuration.

Configuring Git for Specific SSH and GPG Keys

You can run the following Git configuration commands to configure the SSH and GPG keys used for each repo, just replace the key file path, signing key, and user settings to match your own:

git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_johndoe_work -o IdentitiesOnly=yes"
git config user.signingkey "0123456789ABCDEF"
git config user.name "John Doe"
git config user.email "john.doe@example.com"
Enter fullscreen mode Exit fullscreen mode

To get your GPG signing key, use gpg -K. In the output, look for the line starting with "sec" (which stands for secret key). The key ID will be displayed after the key type and size, typically in a format like rsa4096/0123456789ABCDEF. The key listed will likely be longer than the one shown. You only need the last 16 digits of the key but you can use more as long as the ending of the key is included.

Automating Local Repository Configuration

You probably don't want to look up your keys and run these commands manually on each repo that needs it. Luckily, it's pretty easy to use Bash to automate this process. Here's an example that can be used to setup a repo for either one of two identities, one for work projects and one for personal projects.

function git-setup-work() {
    git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_johndoe_work -o IdentitiesOnly=yes"
    git config user.signingkey "0123456789ABCDEF"
    git config user.name "John Doe"
    git config user.email "john.doe@company.com"
}

function git-setup-personal() {
    git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_johndoe_personal -o IdentitiesOnly=yes"
    git config user.signingkey "0123456789ABCDEF"
    git config user.name "JDNickName"
    git config user.email "jdnickname@gmail.com"
}
Enter fullscreen mode Exit fullscreen mode

After defining these functions, source your Bash configuration file and run them to set up your repos as needed.

By following these practices, you can effectively manage multiple Git identities while avoiding common pitfalls associated with SSH and GPG configurations in Git.


  1. https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key 

  2. https://docs.gitlab.com/ee/user/project/repository/signed_commits/ssh.html 

  3. https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification 

  4. https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work 

Top comments (0)