Using GitHub's Deploy Keys

This article is a more comprehensive re-write of this documentation from GitHub itself. The resources I found while doing this myself assumed a lot of knowledge, and for my own future reference, I'll describe what I figured out. I'm doing this on Ubuntu; some other steps are probably necessary for other operating systems.

TLDR: Run ssh-keygen. Update the SSH config to include the new private key. Add the public key to GitHub.

First off, it's worth describing what deploy keys are, and why they are useful. If you have code in a private repository, you'll need to provide login credentials when accessing it. If you want to access the code as part of an automated deployment process, it's a hassle to log in every time (especially if your credentials require 2FA). One solution would be to use OAuth tokens. At the time of writing, OAuth tokens work like a secondary password with a broad scope; there is no way to limit one token to read-only access to a single repository, and thus the token must be protected like a password. Deploy keys are a way to do exactly this: provide easily managed read-only access to a single private repository. Deploy keys are SSH keys that can stand in for credentials in this use case.

Begin by generating SSH keys on the machine to which you are deploying. GitHub describes the process here. In the command line, run ssh-keygen -t rsa -b 4096 -C you@email.com (if you're not on Linux, then ssh-keygen can be run via Git Bash). The first two flags set the encryption type to be 4096-bit RSA. The -C flag sets a comment in the key (this is not necessary, only recommended). You will be prompted to enter a location to save the key. The path is not important, but it's a good idea to name the file after the repository. It's possible to have multiple key files in your SSH configuration, so it's a good idea to have one per deploy key. Then, you will be prompted to enter a passphrase. This must be entered every time the key is accessed, but it's possible to leave it blank. Since the key gives read-only access to a repository that will be cloned on the machine anyway, the security risk to leaving the key blank is trivial. This will generate two files at the given path; one with a .pub extension (for public), and one without an extension (also possibly .pem).

These keys need to be included in the SSH config file before they can be used. This file can be located in one of two places, either ~/.ssh/config (also on Windows) or /etc/ssh/ssh_config. If the file does not exist, then go ahead and create it. Then add the following, replacing the IdentityFile path to match your configuration. This should be the private key (not the .pub).

~/.ssh/config
Host github.com
    Hostname github.com
    User git
    IdentityFile /path/to/private/key

There can be multiple host definitions in the same file. Each Host declaration groups the following declarations, until overridden by the next Host. There are other valid configurations, although they will change the URL by which you are able to access the repository.

Now, the deploy key can be set on GitHub. Copy the contents of the public key (.pub file) over to the repository's deploy keys (https://github.com/youraccount/yourrepository/settings/keys). The easiest way to get the contents of the file is with cat id_rsa.pub. Once the deploy key has been set up on GitHub, you can try cloning the repository on your deployment machine.

The command to clone the repository looks like this: git clone ssh://git@github.com/youraccount/yourrepository.git. This uses the host, hostname, and username provided in the SSH config file. Other repository URL formats might not match the SSH config file, and so would not work. When running this command, you will be prompted for the private key passphrase.

I hope this provided some assistance.

← Read my other thoughts | Written 2020-08-14