GIT:Secure Automated HTTP Credentials

At my employer, we’re using Git for a lot of projects. Unfortunately, the team that set the server up thinks that ssh is far less secure than http[s], so they have disabled it. This leaves the users of their Git server with one remaining option for authentication: our usernames and passwords.

I did a bit of research on this and had a hard time finding the information I was looking for. This is because Git offers its own credentials storage feature. I however use pass for all of my passwords, which has its own credential caching (gnupg). I would rather not maintain my passwords in my password database as well as another one-off password inside of a git config (or have to type it every time the git credential manager times out).

So how do we use an external password manager for painlessly authenticating to a git server over http?

Git Setup

The first step is a lesser-documented git environmental variable. If you run man git and search for the string GIT_ASKPASS, you will see that this variable provides git with the path to a program to be run whenever Git needs a password for an operation.

Unfortunately, the contents of this variable are interpreted such that it is not space delimited, thus making it interpret the entire string as the path to the program. This prevents us from passing our own program arguments within the quoted variable string. However, at runtime, Git will pass one argument: the repo username.

If we can’t specify our own arguments (such as /usr/bin/pass <gituser> | head -n1), we’re left with writing a wrapper script to interpret what Git gives to the askpass program, that will return the appropriate password. Fortunately, this gives us far more flexibility than can be achieved by one line of shell code.

Writing the Wrapper Script

To give git what it needs, we need to write a wrapper script. I put mine in ~/bin/git-askpass (don’t forget to execute chmod +x ~/bin/git-askpass to make it executable). The process is simple. If you want to write your own instead of using mine, you need a few steps.

  1. Take argument 1 as the username

  2. Call your password program (cat \~/.password, call keepass somehow, call pass, etc)

  3. Send to STDOUT only the password

Here is the script I use

\~/bin/git-askpass
#!/usr/bin/env bash

# Set 'export PASSNAME=foo' in your .bashrc and the script will use it.
PASSNAME=${PASSNAME:-default}

main() {
  # Not going to do anything with this probably
  local _username=${1}

  pass ${PASSNAME} | head -n1
}

main ${@}

If you want to use that script unmodified, you should export your own value for PASSNAME in your .bashrc. If you don’t want to do that, you can change the default value specified to the name of your pass entry.

Finally, to tell Git to use that script, also place export GIT_ASKPASS=~/bin/git-askpass in your .bashrc. The next time you try to do a git operation, it will call the wrapper script, which will call pass to give Git the password it needs.

Additional Information

Updating your .bashrc file is just one way you can set this. Another way is to use the git global config. Just run the following command and it will yield the same result.

  git config --global --add core.askpass ~/bin/git-askpass

Last edited: October 14, 2017