A git credential helper implementation that allows using pass as the credential backend for your git repositories. This is achieved by explicitly defining mappings between hosts and entries in the password store.
GPG must be configured to use a graphical pinentry dialog. The shell cannot be used due to the interaction required by git.
sudo python3 setup.py install
For a single user:
python3 setup.py install --user
~/.local/bin is in your
PATH for the single-user installation.
Create the file
This file uses ini syntax to specify the mapping of hosts to entries in the passwordstore database.
Section headers define patterns which are matched against the host part of a URL with a git repository.
Matching supports wildcards (using the python fnmatch module).
Each section needs to contain a
target entry pointing to the entry in the password store with the password (and optionally username) to use.
[github.com*] target=dev/github [*.fooo-bar.*] target=dev/fooo-bar
To instruct git to use the helper, set the
credential.helper configuration option of git to:
In case you do not want to include a full path, a workaround using a shell fragment needs to be used, i.e.:
The option can be set e.g. via:
git config credential.helper '!pass-git-helper $@'
If you want to match entries not only based on the host, but also based on the path on a host, set
true in your git config, e.g. via:
git config credential.useHttpPath true
Afterwards, entries can be matched against
host.com/path/to/repo in the mapping.
This means that in order to use a specific account for a certain github project, you can then use the following mapping pattern:
Please note that when including the path in the mapping, the mapping expressions need to match against the whole path. As a consequence, in case you want to use the same account for all github projects, you need to make sure that a wildcard covers the path of the URL, as shown here:
The host can be used as a variable to address a pass entry. This is especially helpful for wildcard matches:
The above configuration directive will lead to any host that did not match any previous section in the ini file to being looked up under the
git-logins directory in your passwordstore.
includeIf directive available in git >= 2.13, it is also possible to perform matching based on the current working directory by invoking
pass-git-helper with a conditional
To achieve this, edit your
.gitconfig, e.g. like this:
[includeIf "gitdir:~/src/user1/"] path=~/.config/git/gitconfig_user1 [includeIf "gitdir:~/src/user2/"] path=~/.config/git/gitconfig_user2
With the following contents of
mapping_user1.ini, which could contain a
target entry to e.g.
github.com/user1 would always be invoked in
[user] name = user1 [credential] helper=/full/path/to/pass-git-helper -m /full/path/to/mapping_user1.ini
See also the offical documentation for
Defaults suitable for all entries of the mapping file can be specified in a special section of the configuration file named
Everything configure in this section will automatically be available for all further entries in the file, but can be overriden there, too.
Passwordstore Layout and Data Extraction
As usual with pass, this helper assumes that the password is contained in the first line of the passwordstore entry.
Though uncommon, it is possible to strip a prefix from the data of the first line (such as
password: by specifying an amount of characters to leave out in the
skip_password field for an entry or also in the
[DEFAULT] section to apply for all entries:
[DEFAULT] # length of "password: " skip_password=10 [somedomain] # for some reasons, this entry doesn't have a password prefix skip_password=0 target=special/noprefix
pass-git-helper can also provide the username necessary for authenticating at a server.
In contrast to the password, no clear convention exists how username information is stored in password entries.
Therefore, multiple strategies to extract the username are implemented and can be selected globally for the whole passwordstore in the
[DEFAULT] section, or individually for certain entries using the
[DEFAULT] username_extractor=regex_search regex_username=^user: (.*)$ [differingdomain.com] # use a fixed line here instead of a regex search username_extractor=specific_line line_username=1
The following strategies can be configured:
Strategy "specific_line" (default)
Extracts the data from a line indexed by its line number. Optionally a fixed-length prefix can be stripped before returning the line contents.
line_username: Line number containing the username, 0-based. Default: 1 (second line)
skip_username: Number of characters to skip at the beginning of the line, for instance to skip a
user:prefix. Similar to
skip_password. Default: 0.
Searches for the first line that matches a provided regular expressions and returns the contents of that line that are captured in a regular expression capture group.
regex_username: The regular expression to apply. Has to contain a single capture group for indicating the data to extract. Default:
Returns the last path fragment of the passwordstore entry as the username.
For instance, if a regular pass call would be
pass show dev/github.com/languitar, the returned username would be
No configuration options.
Command Line Options
-l can be given as an option to the script to produce logging output on stderr.
This might be useful to understand how the mapping is applied.
-m MAPPING_FILE can be specified to use an alternative mapping file location.
In some automated contexts it might be necessary to prevent GPG from asking for the passphrase (via the agent).
To achieve this, you can disable the complete processing of this helper by defining the environment variable
PASS_GIT_HELPER_SKIP with any content (or no content at all).
pass-git-helper will return immediately in this case, indicating to git that no suitable credentials could be found.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or any later version. This work is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.