Git Passwords in the Keychain

From Exterior Memory
Jump to: navigation, search

Git often accesses remote repositories, and requires authentication to push (and something pull) the data. It can be annoying if git asks for your password each time you push or pull. I'm aware of four solutions that lets you use git push or git pull without a password prompt.

  • Using SSH keys
  • Using credential helpers (git 1.7.9 or higher)
  • Using askpass interface (git 1.7.1 or higher)
  • Using curl's netrc

Using SSH keys

If your repository can be accessed over SSH, the solution is simple. Add your SSH public key to your remote server.

SSH uses asymmetric key pairs for authentication. If you store your public key at the remote server, you can log in with your private key that is on your local machine.

Your SSH public key can be found on your local computer in ~/.ssh/id_rsa.pub. To allow remote logins, store this password on the remote server in ~/.ssh/authorized_keys. For GitHub, upload it to https://github.com/settings/ssh.

If your SSH private key is password protected, you will be prompted for a password after all. I have never tried it, but suspect that the SSH_ASKPASS environment variable can be used to automatically enter this password. If you tested this (with or without success), your contribution is most welcome.

Two-Factor Authentication (2FA)

A somewhat related warning:

If you use 2-factor authentication please be aware that HTTPS-authentication does not work, and git pull and git push will fail with a Invalid username or password error. You need to use SSH authentication. If you enabled 2FA on GitHub, see Changing a remote's URL for information how to change to SSH.

Using credential helpers

If your repository can be accessed over HTTPS, git will ask for your username and password each time you log in. Git itself is not able to store this password, but is able to invoke an external program. Git 1.7.9 introduced the concept of credential helpers, small programs that store or cache passwords and usernames.

More information about credential helpers is available at:

Git credentials on disk or in memory

The two credential helpers always available are:

  • cache to store usernames and passwords in memory. By default it caches usernames and passwords for 15 minutes.
  • store to store usernames and passwords in plain text.

See the man pages of git-credential-cache and git-credential-store respectively.

While store does not encrypt the password file in any way, the default permissions are set to be only user-readable.

Git credential helpers for Mac, Windows or Gnome

The git developers has created three very useful extensions:

  • git-credential-gnome-keyring to access usernames and passwords in the Gnome keyring.
  • git-credential-osxkeychain to access usernames and passwords in the Mac OS X' Keychain
  • git-credential-wincred to access usernames and passwords in the Windows' Credential Manager

These credential helpers are part of "contrib" (contributed code), and may not always be installed with all distributions of git.

To list which credential helpers are available, run:

git help -a | grep credential-

Third Party Credential Helpers

There are even more Credential Helpers:

I am not (yet) aware of a KDE credential helper, though the ksshaskpass package can be invoked using the askpass option (see the next section for details on askpass).

As an example, this is how you can download the osxkeychain credential helper and install it, if it is not part of your distribution for whatever reason:

wget http://github-media-downloads.s3.amazonaws.com/osx/git-credential-osxkeychain
sudo cp git-credential-osxkeychain /usr/local/bin/git-credential-osxkeychain
sudo chmod a+x /usr/local/bin/git-credential-osxkeychain

Configuring a Credential Helper

To enable the osxkeychain credential helper:

git config --global credential.helper osxkeychain

The first time the credential helper is invoked, it requests your username and password. This is subsequently stored in the Keychain. All subsequent attempts, the stored password is used.

If your password has changed, or you like git-password to forget about it, open Apple's Keychain application and remove the entry for the specified URL (e.g. https://github.com/username/Project.git)

Multiple Accounts at the Same Website

By default, git credentials will use the same credentials for each repository in the same domain. So if you have multiple accounts at GitHub (or some other website), you're in a pickle. The easiest solution is to set the username in the repository (thus not globally). (Warning: this has not been tested yet)

cd myrepository
git config credential.https://example.com.username myusername

To use different credentials by default for each domain, set

git config --global credential.useHttpPath true

Using askpass interface

Before the introduction of the credential helpers, git is able to invoke external program to retrieve a password, using the askpass setting. When this setting is set, git invokes the specified program to ask for the password. It's very similar to a git credential helper, although according to the git developers less convenient.

There are at least two askpass helpers:

  • git-password by Samuel Kadolph which interfaces with the Mac OS X Keychain
  • ksshaskpass to interface with the KDE Wallet.

git-password for Mac OS X

To install and configure git-password:

wget https://github.com/downloads/samuelkadolph/git-password/git-password
sudo cp git-password /usr/local/bin/git-password
sudo chmod a+x /usr/local/bin/git-password

git config --global core.askpass /usr/local/bin/git-password

(The core.askpass option only works in git 1.7.3 and up. If you have git 1.7.1 or 1.7.2, set the GIT_ASKPASS global variable in your shell: export GIT_ASKPASS="/usr/local/bin/git-password".)

The first time git-password is invoked, it requests your username and password. This is subsequently stored in the Keychain. All subsequent attempts, the password is used.

If your password has changed, or you like git-password to forget about it, open Apple's Keychain application and remove the entry for the specified URL (e.g. https://github.com/username/Project.git)

Using curl's netrc

If all else fails, you can also store passwords in plain text in a .netrc file. This works because git uses the curl library, which accesses this file. Store this file in your home directory (~/.netrc)

Here is an example .netrc file:

 machine github.com login myusername password mypasswd

with "myusername" and "mypassword" replaced with your actual username and password.

Since the passwords in the .netrc file are stored in plain text, makes sure that the file is not readable by other users.