Github + Multiple Repository SSH Deploy Keys

I use Jenkins for CD/CI, but was running into the issue of deleted files not being removed from the target server. My solution to this issue was to only use Jenkins to generate the configuration and deployment scripts which are then transferred to the server via SSH. The deployment script updates from Github using a deployment key for that repository specifically, and Github won’t let you use the same key more than once. That means that if you want to have the same user deploying from multiple repositories you will need to be able to specify a specify key for each repository.

Generate SSH Keys

To do this you will first need to generate an SSH key for each of the Github repositories you want to deploy from, named after the repository. So if you have repo1 and repo2 for example, I would name the keys github_repo1 and github_repo2. Run ssh-keygen twice to generate each key, as seen below.

[username@www01 ~]$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_rsa): /home/username/.ssh/github_repo1
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/username/.ssh/github_repo1.
Your public key has been saved in /home/username/.ssh/github_repo1.pub.
The key fingerprint is:
0a:15:7c:6c:e5:f7:fa:d2:e6:9e:18:ed:df:b7:e4:7d [email protected]
The key's randomart image is:
+--[ RSA 2048]----+
|     ... ..      |
|      ..+.       |
|      .o  . .    |
|     .     . .   |
|    .   S     .  |
|     . .     o   |
|      .     o... |
|            .==.E|
|            .=*+B|
+-----------------+

Configure Github Deploy Keys

Next we need to get the public part of the SSH key. Use cat to print it to the terminal, then cut and paste the results into Github.

[username@www01 ~]$ cat /home/username/.ssh/github_repo1.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDZtdWXgqtfhibmL5PsEly1Toe35ZfHiBHo+YfHT4pQBp+k7pf9KWhWeUdG0+LrAiYfN9sJb21frSza9uUchJdlDKYuxr0vkiZ9YrdZ0G9yENQYy7lL4lKRDuqa+1DA/bMJfiBIIsdPf+dQb32IUNQ+tzqvmab1Hxm1JzGbRE2ycfExSknEcRuvzuAYM/jKOE+IhLVqGgteUnmKQHBvVoxZQz2p80ZgoVn+lKFi2u7vSnGzJWgH9ffMgWhKLFAGMfRiAMAXX//Qb7XXzbSjubxbJBRkz9Flw4h/Os30UKQ2k4tO+EbYFtWiPXwEDbJB4+iyN5882szXfZdE+nGnuVP/ [email protected]

With your public key in hand, visit https://github.com/username/repo1 (adjusting for your username/organization and repository name), and then click “Settings” on the top right followed by “Deploy keys” on the left hand menu. Click the “Add deploy key” button, give your key a name, and then paste in the public key contents, and save by clicking the “Add key” button.

Test Deploy Keys

To test that the key is working use ssh and specify your private key before connecting to Github. It should display your username/organization and repository name in the response before disconnecting.

[username@www01 ~]$ ssh -i /home/username/.ssh/github_repo1 [email protected]
PTY allocation request failed on channel 0
Hi username/repo1! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

Configure SSH Client

Next we need to specify which SSH key to use for each repository using the ~/.ssh/config file. Edit it to create entries for each of the repositories you want to specify a deploy key for.

Host repo1 github.com
Hostname github.com
IdentityFile /home/username/.ssh/github_repo1

Host repo2 github.com
Hostname github.com
IdentityFile /home/username/.ssh/github_repo2

SSH will refuse to use the config file if it has the wrong permissions, so set them to 400.

chmod 400 /home/username/.ssh/config

Clone Git Repository Using Alias

Now we can clone the repository using the SSH alias which will in turn use the correct SSH key. You will still need to specify your username/organization + repository name after the colon. If you want to use a different directory just append it to the end. When you run git pull, or git checkout, etc from within the checkout directory it will now use this SSH alias and correct keys to update the local files.

git clone git@repo1:username/repo1.git

If you want to include this repository in the package.json of a different project (including private ones you have checked out using an alias), make sure to refer to it by the SSH alias as well.

npm i git@repo1:username/repo1.git
{
  "name": "example",
  "dependencies": {
    "repo1": "git@repo1:username/repo1.git"
  }
}

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *