When working with a remote git repository, typing the password every single pull/push is quite tiresome.
A good way would be to store the credentials locally, however the most common way of doing so is just wrong from a security point of view.
Most people will search online for “how to store git credentials” and resort to this “solution”:
$ git config credential.helper store
This “trick” will actually create a plain text file
~/.git-credentials with the password, when it’s typed the next time with
git pull or
git push commands.
Here’s what this file usually looks like:
This file gets 0600 permission by default, so only the current user can see it.
But that’s not good enough.
It starts with a simple command:
$ shred -u ~/.git-credentials
This command makes sure to remove the file and overwrite where it was stored on the drive, making it impossible to recover even if someone physically got hold of the machine.
Once we made sure nobody will ever be able to recover our password again, we’re left with two main options for encrypting the credentials.
The GNOME way:
This solution simply uses GNOME’s
libsecret for encrypting and storing the credentials. However, even though it’s GNOME, it should work on basically any UNIX system.
- Get and install
libsecretwhich presents in any modern Linux distribution’s software repository.
- Configure git to use
$ git config --global credential.helper libsecret
This will effectively create a file
~/.gitconfigwith the following content (or append to the existing one):
[credential] helper = libsecret
On the next
pushcommands, a popup should come up asking for a password:
This password will be used for encrypting what’s called a “keyring” which is used for encrypting the git password.
All keyrings are stored in
With the default settings it’s required to type in the password only once per login session, which is much more convenient compared to each
Encrypting using GnuPG
For people who use pass, this should be the preferred option.
- Create a new password file (the name doesn’t matter):
$ pass add -m <name>
-mswitch allows typing multi-line credentials.
- Here’s the content that should be inside:
machine <domain> protocol <http|https|ssh> login <username> password <password>
machine→ The repository’s domain name. (Ex: GitHub:
protocol→ Whatever fits the repository:
password→ The username and password for the service
Note: It’s possible to store multiple service’s credentials. Simply add another paragraph for each service.
- Optional: By default, the credentials file is stored at
passmain directory (usually
~/.password-store) but I recommend linking it to
$ ln -s $HOME/.password-store/<file-name> $HOME/.git.gpg
Note: When linking files it’s usually safer to use
~/to indicate the home directory.
- Next, configure
gitaccordingly, to use the
$ git config --global credential.helper "netrc -v -f <path-to-file>"
Encrypting manually using GnuPG (without
Those who don’t use
pass can still use this option, however it requires (a little bit of) extra work:
- Create a file with the content mentioned in step 2 above.
- Generate a new GPG key (if there’s none already):
$ gpg --gen-key
- Encrypt the file:
$ gpg -e -r <recipient> <path-to-file>
<recipient>is usually the email address (of yourself). Use
gpg --list-keysto confirm.
- Continue to step 4 above.
“Not a git command” error
git pull or
git push for the first time, the following error might show up:
git: 'credential-<libsecret|netrc>' is not a git command. See 'git --help'.
It happens because on some distribution the required binary is not in
$PATH or even compiled.
To fix this, we need to find a file named
git-credentials-netrc for GnuPG.
Then, choose one of the following:
git-credentials-<libsecret|netrc>to any directory in
git-credentials-<libsecret|netrc>from this location. Simply re-run the config command:
$ git config --global credential.helper $PWD/git-credentials-<libsecret|netrc>
Note: We’re using
$PWDthat indicates the current path. This should be where the
- If the target file is in
git-credentials-prefix will be automatically prepended to
--helpfor more information (when running the script directly) and
If only a file named
git-credentials-libsecret.c is present, it means we have to compile it.
Make sure basic build packages are present on the system (
build-essential on Debian-based systems, for example):
$ sudo make
sudo part is essential since we’re inside
/usr which is probably not owned by the current user.
This process should end in a fraction of a second on any machine.
“lookup failed” error
On Arch, the following error may show up:
** (process:6182): CRITICAL **: 22:10:58.547: lookup failed: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.secrets was not provided by any .service files
It can be fixed by installing the
gnome-keyring package which provides the necessary service for
libsecret to run.
~/.git-credentials keeps coming back
Some repositories might have been configured to use the
store plugin locally and those settings override the global ones.
To reset this setting, simply run inside the suspected repository:
$ git config --unset credential.helper
By the way, it’s possible to confirm (or change) those settings manually by editing
.git/config in every repository.
Can’t type in GnuPG password on a headless machine
GnuPG assumes that it runs inside an Xserver environment and tries to launch a window asking for a password. However, on a headless machine it’s not the case.
There’s a global variable
$GPG_TTY that can be set to fix this:
$ export GPG_TTY=$(tty)
Note: This line can be added to
.zshrc for convenience.
Extra: GUI for credentials management
The Seahorse GUI utility can be used for managing all passwords stored by
libsecret or the keys for GnuPG.
It can even manage SSH keys and do a lot more.