Pushing Git Changes without Typing Passwords
I'm lazy and use SSH public keys with my GitHub/GitLab repositories so I don't have to type a long password every time I push to one of my repos. This is a poor security practice, but let's document how it works anyway!
The short version: you upload a public key to your account settings on GitHub/GitLab. After that, these services will authenticate using that public key to check that you can prove you have the corresponding private key. If you do, then your git commands will run...no passwords typed!
The tricky part is determining why your SSH operations fail to work. It boils down to specifying WHICH KEYS ARE OFFERED and knowing how to SPECIFY THE CORRECT HOST URL, which is not as straightforward as you would think. There are two main concepts behind making it work:
remoteis an alias for the URL of the repository you are tracking. This is set using the
git remote add <alias> <url>command. For SSH the URL is the same format as a SSH login (e.g.
email@example.com:/path/to/repo/reponame.git).Note that the usernane should be
gitfor both GitLab and GitHub, not your login name KEY: The
gitlab.comin the connection string can refer to a
Hostentry in SSH config.
Your public/private SSH key pairs (aka "identities") are typically stored in your user directory at
~/.sshThe files with
.pubextensions are your public keys, the ones without any extension are private keys. Don't share your private key! Don't forget to back them up when reinstalling the operating system! A program called
ssh-agentis loaded to "offer" a list of identities to the remote host, which will then try them one-after-the-other until it gets a response that PROVES you are indeed a valid user of the repository you're accessing. KEY: The
Hostentry in SSH config can be be told to offer a different identities even to the same domain (e.g.
1. Choosing what identity keys are offered
The available key pairs ("identities") are stored in
~/.ssh and referred to in the
~/.ssh/config settings file. However, it is the helper program
ssh-agent that does the actual communication with a remote server to authenticate you before your git commands are allowed to run. This helper program usually runs automatically on computer startup.
When using the command line,
ssh-agent is initialized with a set of keys using the
ssh-add ~/.ssh/keyname command. This temporarily adds the identities you want to authenticate with. You also use this command to remove all identities with
ssh-add -D to start fresh. Finally, you can use
ssh-add -l to list all the currently loaded identities. To connect to different remote hosts with SSH, you use these commands to load/unload the proper identities for each.
Remember, though, that I'm choosing convenience over security. There are several shortcuts you can add by adding Host entries to the
2. Setting the correct
The Host entries in
~/.ssh./config can be used as an address in an SSH connection string. This is super important, because it allows you to specify a particular IdentityFile to go with a particular HostName. Consider these two examples defined in the same
# address one Host github.com HostName github.com User git PreferredAuthentications publickey IdentityFile /Users/dsri/.ssh/id_rsa # address two Host github.com-extra HostName github.com User git PreferredAuthentications publickey IdentityFile /Users/dsri/.ssh/github-ed25519
Note: At the time of this writing, the SourceTree git client adds its own entries to
~/.ssh/config so you should review them, particularly when setting a git remotes for the first time with a new repo.
It is through the use of Host and the IdentifyFile that you create an alias for a particular connection. Note how both Host entries use the same user and HostName, but have different
You can use the command
ssh -Tvvv <Host> to debug the connection authentication and see which identities are being offered and tested; if you don't see the one you expect, your config might be goofed up. Remember,
<Host> refers to one of the
Host entries in
ssh -Tvvv github.com ssh -Tvvv github-extra.com
For further convenience, you can add the
AddKeysToAgent settings (the last tow are MacOS only):
Host github.com-second HostName github.com User git PreferredAuthentications publickey IdentityFile /Users/dsri/.ssh/id_rsa IdentitiesOnly yes # use only IdentityFiles in this entry UseKeychain yes # macos: store any passwords in apple keychain AddKeysToAgent yes # macos: load this key to ssh-agent on startup
The MacOS settings are conveniences that would be handled in Linux or Windows differently.
3. Setting Git Repository Remotes
If you are using an SSH Host alias that is NOT just "github.com" or "gitlab.com", you MUST use change your remote URL accordinglycough SourceTree . For example, say you create a new repo on GitHub and want to add it as a remote to a local repo. GitHub provides instructions after you create the enw repo that look like this:
$ git remote add origin firstname.lastname@example.org:dsriseah/myrepo.git $ git push -u origin main $ git remote -v
Note: 'origin' is the name of the remote, and is an arbitrary convention much like the use of
master are used to refer to the "main branch" of a repo.
remote add origin line, the host here does not refer to the example config just above it. If my
github.com-second host alias is not the one I used with the github account, authentication will fail! The
remote add has to be changed to:
$ git remote add origin email@example.com:dsriseah/myrepo.git
Command Cheat Sheet
eval ssh-agent # run the ssh agent if it's not already running ssh-add ~/.ssh/keyFile # load identity for 'keyFile' ssh-add -l # list loaded identities ssh-add -D # unload all identities
ssh -T domain.com # test if can connect with current config ssh -Tvvvv domain.com # add a ton of debug output