Configuring multiple SSH Deploy Keys on GitHub from one server

Configuring multiple SSH Deploy Keys on GitHub from one server

Jul 29, 2019

When I was deploying Kourty on a VPS by following my previous article, I had three projects I needed to clone on the server. I wanted to use Deploy Keys on GitHub. Deploy Keys are pretty much read-only keys for your repositories. They can be found by going to your GitHub repository -> Settings -> Deploy Keys:

github-deploy-key

I find them to be best practice for getting your code on your prod server as these only allow for servers to clone the code and not write to the repositories.

While setting up these deploy keys for Kourty, I discovered that you can only use one SSH key as a deploy key. You run into this error if you use the key more than once:

deploy-key-in-use

This means I had to create three SSH keys for the three repositories. I did that by running ssh-keygen on my server three times. Each time creating a new pair of RSA public/private keys in the /root/.ssh directory on my server. It looked like:

key-one.pub key-one key-two.pub key-two key-three.pub key-three

For each repository I needed to clone onto my server, I then added the .pub keys into the previously mentioned Deploy Key settings in repositories on GitHub.

This was all good until I ran into a problem with specifing which SSH key to use when cloning the repositories. Without configuration, SSH will always default to the id_rsa key in ~/.ssh. I wanted a dynamic way for the ssh keys I created to be used.

The first solution I found on StackOverflow to run Git commands with a GIT_SSH_COMMAND like:
GIT_SSH_COMMAND="ssh -i ~/.ssh/key-one" git pull

This worked and I created a script that ran these Git commands, but I wanted a more elegant solution - one where I could just run Git commands as normal.

The second and my favourite solution was to create a ssh_config file within SSH. I created it by running touch ~/.ssh/config then placing in the following:

Host repository-one
  Hostname github.com
  User git
  IdentityFile ~/.ssh/key-one
Host repository-two
  Hostname github.com
  User git
  IdentityFile ~/.ssh/key-two
Host repository-three
  Hostname github.com
  User git
  IdentityFile ~/.ssh/key-three

With this new config, the remote URLs used for repositories had to be changed. Instead of:

git@github.com:HarveyD/repository-one.git

I would use:

repository-one:HarveyD/repository-one.git

Making sure that repository-one mapped to what was in the ssh_config file in the Host section.

With this new config and correct remote URLs, I could now run all git commands for all the repositories with their very own SSH key!

If you were using Git Submodules like I was, you'd update your .gitmodules file from:

[submodule "repository-one"]
	path = repository-one
	url = git@github.com:HarveyD/repository-one.git
[submodule "repository-two"]
	path = repository-two
	url = git@github.com:HarveyD/repository-two.git

To:

[submodule "repository-one"]
	path = repository-one
	url = repository-one:HarveyD/discaper.git
[submodule "repository-two"]
	path = repository-two
	url = repository-two:HarveyD/repository-two.git

Now go enjoy your multiple SSH Deploy Keys with no overhead!

Harvey Delaney

Front End Engineer II at Amazon Web Services

Exclusive Usenet provider deals

Harvey's essential software engineering books

1

The Pragmatic Programmer: From Journeyman to Master

2

Clean Code: A Handbook of Agile Software Craftsmanship

3

Code Complete: A Practical Handbook of Software Construction

4

Design Patterns: Elements of Reusable Object-Oriented Software

Harvey is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com
Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.