Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pwillis-els/172c6ce89f5226199b1683a4c8af7a3d to your computer and use it in GitHub Desktop.
Save pwillis-els/172c6ce89f5226199b1683a4c8af7a3d to your computer and use it in GitHub Desktop.
Why you should use HTTPS instead of SSH for GitHub credential access

About

HTTPS and Personal Access Tokens are the preferred method to use GitHub, rather than SSH keys. Here I'll explain why.

SSH key problems

Accepting Host Keys

If you access GitHub using SSH, you're required to accept the host keys of github.com the first time you pull a repo. This might not be a problem if you're using your own workstation, as the cached host keys will stick around for a long time.

But if you're using a Docker container or some other ephemeral storage, you may have to accept the host keys every time you pull the repository. If you're using automation, this becomes more complicated as you need to work around the host key acceptance.

You might create some automation to automatically accept the host keys. Or you might pre-cache the host keys somewhere, which will require you to periodically update them in case GitHub changes their host keys. Or you can disable host key checking altogether - but this defeats SSH encryption entirely by allowing a Man-in-the-Middle attacker to impersonate Github.com, and you'll never know. And even if you're using a workstation, if there are hundreds of users in your company, each one is an opportunity for a Man-in-the-Middle to fake Github.com the first time a user clones a repository on their workstation.

So SSH Host Keys are really a maintenance headache and a potential security nightmare.

Selecting the right SSH key

If you have only one Github account and one SSH key that you use for everything, using SSH is very straightforward. You just have your one default SSH key, and every time you use a Github repo, it selects the correct SSH key.

But if you have more than one Github account, or more than one SSH key added to GitHub, there is no easy way to specify what SSH key to use with GitHub. Github only allows any given SSH key to be added to a single Github account. This is because it uses your SSH key to determine which GitHub account you are using when you clone a repository from GitHub. The GitHub SSH URI ("ssh://git@github.com/") does not tell GitHub who your user is, so it has to be detected from your SSH key.

By default, Git just sends whatever your default SSH key is. So if you have multiple repos using multiple keys, you'll have to find your own way to juggle which SSH key is used for which repository.

HTTPS advantages

No Host Keys

HTTPS uses TLS certificates for encryption. Your computer has a downloaded list of CA certificates, and one of those will have signed the TLS certificate for GitHub.com. Therefore, any time you pull a repository from GitHub.com, it will always be encrypted. There is no opportunity for Man-in-the-Middle attack, and there is no maintenance to perform.

Easy to Select the Right Credentials

When you clone a GitHub repository with HTTPS ("https://github.com/") by default it will prompt you for your username and password. (Actually, you should use a Personal Access Token instead of your password; it's more secure and more flexible, but more on that later)

But let's say you want it to automatically pick up your credentials, rather than having to type it in each time. That's actually easy! First, create a .netrc file in your $HOME directory with your username and personal access token. (Make sure you change the permissions on this file so only your user can read it)

# ~/.netrc
machine github.com    login my-username    password ofh92hf9oh2rh2hf2hrhf9huwhucjhbsdjvhjwiuh

Next, change the remote origin for your GitHub repository to point to the correct URI:

$ git remote -v
origin  https://github.com/my-username/some-repo.git (fetch)
origin  https://github.com/my-username/some-repo.git (push)
$ git remote remove origin
$ git remote add origin https://my-username@github.com/my-username/some-repo.git
$ 

Now when you use that repository, Git will automatically retrieve the correct user's login credentials from your .netrc file. You can use this method for as many users as you want. There are more secure methods (such as using credential keychains), but this is pretty simple.

If you need to use multiple different personal access tokens per user, see this cheat sheet for "per-project" solutions. Basically you're gonna have to modify some Git settings, there's no easier way around it.

API access

To use the GitHub API, you have to use a Personal Access Token anyway. So you might as well generate one Personal Access Token and use it for both cloning repos and using their API. (It's more secure to have multiple Personal Access Tokens with restricted scopes, however)

Port 443 is always open

On many networks, port 22 (the SSH port) is blocked. But pretty much every network allows communication over port 443.

GitHub actually has a workaround to allow you to use SSH over port 443, but why go to the trouble if you don't need to?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment