Per project git ssh keys

papepathe profile image Papa Pathé SENE ・1 min read

As a professional software developer you work on different projects for distributed clients.

You have to deal with many source code management services and ssh keys.

For my case i have a professional ssh key and a personal one. I would like to be able to just run git push or pull without specifying the ssh-key to use and git will figure out the rest.

First approach

We can use the environment variable to switch the ssh-key used by git the authenticate push & pull requests.

GIT_SSH_COMMAND="ssh -i /path/to-your/ssh-key" git push your-origin your-branch

Second approach

We all agree that it's boring to always specify the ssh key. Thanks to the community, git has a sshCommand configuration variable. We will use it and configure a per project ssh key.

git config core.sshCommand "ssh -i /path/to-your/ssh-key"


git config sshCommand


Editor guide
ferricoxide profile image
Thomas H Jones II

I got tired of dealing with the "override global settings with per-project settings" problem.

Usually, when I'm doing work for a given customer, there's several code-projects I'll have to deal with for them. Doing a local git config in each, individual project kinda sucks. So, instead, I started to set up my git directory as a tree-of-trees. At the top level I have ${HOME}/GIT/<CUSTOMER_ROOT>. Within that, I have a "faux root" and a "projects" subdirectory. The "faux root" subdirectory contains my customer-global .gitconfig, ssh-hey(s) and signing-keys (for that customer's projects), plus localized ${HOME} dot-files (.bashrc, etc.). The "projects" subdirectory contains my local git-clones.

With this setup, I can fire up a really basic docker (podman, actually) container that I mount the "faux root" to as the container's root user's ${HOME} (and the "project" subdirectory to another location within the container). That way, my user.email, signing-key, ssh-keys, etc. are all set up for each of that customer's projects without having to:

  • git config --local within each project to overide my global configs
  • Worry that I made any commits with the wrong author email
  • Worry that I made any commits with the wrong signing-key
  • Worry that I presented the wrong SSH key to the remote git server

It also means that I can ensure that a given container only contains the tooling (and versions) necessary for that customer's projects. Plus, when I fire up the container, I can set its default command to ssh-agent (specifying a predictable SSH_AUTH_SOCK that can be put in the faux root's .bashrc) such that, when I attach to it, the SSH-agent is ready-to-go – allowing me to attach/detach/re-attach without having to re-instantiate the ssh-agent or reload keys..

It's probably a bit of a "heavy" solution, but it works. That said, I'm always looking for easier ways to ensure that I don't "oops" anything when I work for Customer A on Monday and Customer B on Tuesday. =)

ferricoxide profile image
Thomas H Jones II

Actually, in digging around, further, looks like one can set per-directory includeIf statements to one's global git configuration file. Looks like, if it works the way it appears it might, I'd be able to leverage it and throw away the containers (that said, the "sandbox" nature of a container still has other utility). Maybe I'll investigate that, this week: first is to check which git client-versions support it (I'm still usually dev'ing from EL7 and its ancient git client).