Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to configure multiple deploy keys for different private github repositories on the same computer without using ssh-agent

Let's say alice is a github.com user, with 2 or more private repositories repoN. For this example we'll work with just two repositories named repo1 and repo2

https://github.com/alice/repo1

https://github.com/alice/repo2

You need to be to pull from these repositories without entering a passwords probably on a server, or on multiple servers. You want to perform git pull origin master for example, and you want this to happen without asking for a password.

You don't like dealing with ssh-agent, you have discovered (or you're discovering now) about ~/.ssh/config a file that let's your ssh client know what private key to use depending on Hostname and username, with a simple configuration entry that looks like this:

Host github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/alice_github.id_rsa
  IdentitiesOnly yes

So you went ahead and created your (alice_github.id_rsa, alice_github.id_rsa.pub) keypair, you then also went to your repository's .git/config file and you modified the url of your remote origin to be something like this:

[remote "origin"]
        url = "ssh://git@github.com/alice/repo1.git"

And finally you went to the repository Settings > Deploy keys section and added the contents of alice_github.id_rsa.pub

At this point you could do your git pull origin master without entering a password without issue.

but what about the second repository?

So your instinct will be to grab that key and add it to repo2's Deploy keys, but github.com will error out and tell you that the key is already being used.

Now you go and generate another key (using ssh-keygen -t rsa -C "alice@alice.com" without passwords of course), and so that this doesn't become a mess, you will now name your keys like this:

  • repo1 keypair: (repo1.alice_github.id_rsa, repo1.alice_github.id_rsa.pub)
  • repo2 keypair: (repo2.alice_github.id_rsa, repo2.alice_github.id_rsa.pub)

You will now put the new public key on repo2's Deploy keys configuration at github.com, but now you have an ssh problem to deal with.

How can ssh tell which key to use if the repositories are hosted on the same github.com domain?

Your .ssh/config file points to github.com and it doesn't know which key to use when it's time to do the pull.

So I found a trick with github.com. You can tell your ssh client that each repository lives in a different github.com subdomain, in these cases, they will be repo1.github.com and repo2.github.com

So first thing is editing the .git/config files on your repo clones, so they look like this instead:

For repo1

[remote "origin"]
        url = "ssh://git@repo1.github.com/alice/repo1.git"

For repo2

[remote "origin"]
        url = "ssh://git@repo2.github.com/alice/repo2.git"

And then, on your .ssh/config file, now you will be able to enter a configuration for each subdomain :)

Host repo1.github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/repo1.alice_github.id_rsa
  IdentitiesOnly yes

Host repo2.github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/repo2.alice_github.id_rsa
  IdentitiesOnly yes

Now you are able to git pull origin master without entering any passwords from both repositories.

If you have multiple machines, you could copy the keys to each of the machines and reuse them, but I'd advise doing the leg work to generate 1 key per machine and repo. You will have a lot more keys to handle, but you will be less vulnerable if one gets compromised.

@john2x

This comment has been minimized.

Copy link

john2x commented May 26, 2017

It's useful to have the following entry in .ssh/config while doing the initial clone of the repositories, since the remote urls will default to "git@github.com".

Host github.com
  HostName github.com
  User git
  IdentityFile /home/alice/.ssh/repo1.alice_github.id_rsa
  IdentitiesOnly yes

Then once repo1 has been cloned, edit .ssh/config again to use the repo2 key for Host github.com.

@mannesiddhardha

This comment has been minimized.

Copy link

mannesiddhardha commented Jul 10, 2017

Hi,
From the above scenario, as the number of repository's increases I have to generate new deploy key's for them by updating the .ssh and .git config's.

@blvz

This comment has been minimized.

Copy link

blvz commented Aug 26, 2017

Thanks for the info! I've created a script to automate this:
https://gist.github.com/blvz/8eeebacae11011c25fc79eff12f49ae9

Install and use:

$ curl https://gist.githubusercontent.com/blvz/8eeebacae11011c25fc79eff12f49ae9/raw/6f2f7f3709a0fe852d8a3a5bb125325e3ffbc7d8/gh-deploy-clone.sh > /usr/local/bin/gh-deploy-clone
$ chmod +x /usr/local/bin/gh-deploy-clone
$ gh-deploy-clone user/repo
@Aamir010

This comment has been minimized.

Copy link

Aamir010 commented Sep 6, 2017

What should I put in "Host" if I do have "Organizaton/RepoName"

@phpguru

This comment has been minimized.

Copy link

phpguru commented Feb 27, 2018

@Aamir010 You can use any hostname you want. E.g. yourrepo.github.com. The key to making that work is when you edit the ~/.git/config of your repo and change the origin to ssh://git@yourrepo.github.com. As long as you use the same string (yourrepo) in both places, it works.

@iron-cherep

This comment has been minimized.

Copy link

iron-cherep commented Mar 1, 2018

works like a charm 👍

@cowlinator

This comment has been minimized.

Copy link

cowlinator commented Apr 18, 2018

An important point of information, for those of us not familiar with .ssh config files, is that the HostName identifies the real url-domain, whereas the Host is a alias ( in this case, the alias takes the form of a url-domain ).
This technique can also be used with Github Enterprise domains.

@jakubdal

This comment has been minimized.

Copy link

jakubdal commented May 3, 2018

If you clone the repository with the subdomain (eg. git clone git@repo1.github.com/alice/repo1.git) you can skip editing your .git/config file, as the origin will already be set to subdomain. However you have to add the subdomain to your clone command manually.

@pudgereyem

This comment has been minimized.

Copy link

pudgereyem commented May 23, 2018

Not sure is this something only related to me or not, but thought I might as well post it here if it helps anyone.

I had to change the url slightly in order to get it to work (putting : instead of /). It might have to do with the fact that the repository is under an Organization.

[remote "origin"]
        url = "ssh://git@repo1.github.com/alice/repo1.git" <-- original, doesn't work
        url = "ssh://git@repo1.github.com:alice/repo1.git" <-- works for me
                                         ^-- colon instead of slash
@nick-brady

This comment has been minimized.

Copy link

nick-brady commented Sep 3, 2019

I found the following gist a little more helpful... though this one tuned me on to solving it this way! Thank you!

https://gist.github.com/jamesmcfadden/d379e04e7ae2861414886af189ec59e5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.