Git credentials helper windows

7.14 Git Tools — Credential Storage

Credential Storage

If you use the SSH transport for connecting to remotes, it’s possible for you to have a key without a passphrase, which allows you to securely transfer data without typing in your username and password. However, this isn’t possible with the HTTP protocols – every connection needs a username and password. This gets even harder for systems with two-factor authentication, where the token you use for a password is randomly generated and unpronounceable.

Fortunately, Git has a credentials system that can help with this. Git has a few options provided in the box:

The default is not to cache at all. Every connection will prompt you for your username and password.

The “cache” mode keeps credentials in memory for a certain period of time. None of the passwords are ever stored on disk, and they are purged from the cache after 15 minutes.

The “store” mode saves the credentials to a plain-text file on disk, and they never expire. This means that until you change your password for the Git host, you won’t ever have to type in your credentials again. The downside of this approach is that your passwords are stored in cleartext in a plain file in your home directory.

If you’re using a Mac, Git comes with an “osxkeychain” mode, which caches credentials in the secure keychain that’s attached to your system account. This method stores the credentials on disk, and they never expire, but they’re encrypted with the same system that stores HTTPS certificates and Safari auto-fills.

If you’re using Windows, you can install a helper called “Git Credential Manager for Windows.” This is similar to the “osxkeychain” helper described above, but uses the Windows Credential Store to control sensitive information. It can be found at https://github.com/Microsoft/Git-Credential-Manager-for-Windows.

You can choose one of these methods by setting a Git configuration value:

Some of these helpers have options. The “store” helper can take a —file

argument, which customizes where the plain-text file is saved (the default is

/.git-credentials ). The “cache” helper accepts the —timeout option, which changes the amount of time its daemon is kept running (the default is “900”, or 15 minutes). Here’s an example of how you’d configure the “store” helper with a custom file name:

Git even allows you to configure several helpers. When looking for credentials for a particular host, Git will query them in order, and stop after the first answer is provided. When saving credentials, Git will send the username and password to all of the helpers in the list, and they can choose what to do with them. Here’s what a .gitconfig would look like if you had a credentials file on a thumb drive, but wanted to use the in-memory cache to save some typing if the drive isn’t plugged in:

Under the Hood

How does this all work? Git’s root command for the credential-helper system is git credential , which takes a command as an argument, and then more input through stdin.

This might be easier to understand with an example. Let’s say that a credential helper has been configured, and the helper has stored credentials for mygithost . Here’s a session that uses the “fill” command, which is invoked when Git is trying to find credentials for a host:

This is the command line that initiates the interaction.

Git-credential is then waiting for input on stdin. We provide it with the things we know: the protocol and hostname.

A blank line indicates that the input is complete, and the credential system should answer with what it knows.

Git-credential then takes over, and writes to stdout with the bits of information it found.

If credentials are not found, Git asks the user for the username and password, and provides them back to the invoking stdout (here they’re attached to the same console).

Читайте также:  Windows 10 не ставится видеодрайвер

The credential system is actually invoking a program that’s separate from Git itself; which one and how depends on the credential.helper configuration value. There are several forms it can take:

Runs git-credential-foo -a —opt=bcd

Runs /absolute/path/foo -xyz

Code after ! evaluated in shell

So the helpers described above are actually named git-credential-cache , git-credential-store , and so on, and we can configure them to take command-line arguments. The general form for this is “git-credential-foo [args] .” The stdin/stdout protocol is the same as git-credential, but they use a slightly different set of actions:

get is a request for a username/password pair.

store is a request to save a set of credentials in this helper’s memory.

erase purge the credentials for the given properties from this helper’s memory.

For the store and erase actions, no response is required (Git ignores it anyway). For the get action, however, Git is very interested in what the helper has to say. If the helper doesn’t know anything useful, it can simply exit with no output, but if it does know, it should augment the provided information with the information it has stored. The output is treated like a series of assignment statements; anything provided will replace what Git already knows.

Here’s the same example from above, but skipping git-credential and going straight for git-credential-store:

Here we tell git-credential-store to save some credentials: the username “bob” and the password “s3cre7” are to be used when https://mygithost is accessed.

Now we’ll retrieve those credentials. We provide the parts of the connection we already know ( https://mygithost ), and an empty line.

git-credential-store replies with the username and password we stored above.

/git.store file looks like:

It’s just a series of lines, each of which contains a credential-decorated URL. The osxkeychain and wincred helpers use the native format of their backing stores, while cache uses its own in-memory format (which no other process can read).

A Custom Credential Cache

Given that git-credential-store and friends are separate programs from Git, it’s not much of a leap to realize that any program can be a Git credential helper. The helpers provided by Git cover many common use cases, but not all. For example, let’s say your team has some credentials that are shared with the entire team, perhaps for deployment. These are stored in a shared directory, but you don’t want to copy them to your own credential store, because they change often. None of the existing helpers cover this case; let’s see what it would take to write our own. There are several key features this program needs to have:

The only action we need to pay attention to is get ; store and erase are write operations, so we’ll just exit cleanly when they’re received.

The file format of the shared-credential file is the same as that used by git-credential-store .

The location of that file is fairly standard, but we should allow the user to pass a custom path just in case.

Once again, we’ll write this extension in Ruby, but any language will work so long as Git can execute the finished product. Here’s the full source code of our new credential helper:

Here we parse the command-line options, allowing the user to specify the input file. The default is

This program only responds if the action is get and the backing-store file exists.

This loop reads from stdin until the first blank line is reached. The inputs are stored in the known hash for later reference.

This loop reads the contents of the storage file, looking for matches. If the protocol and host from known match this line, the program prints the results to stdout and exits.

We’ll save our helper as git-credential-read-only , put it somewhere in our PATH and mark it executable. Here’s what an interactive session looks like:

Читайте также:  Как установить brave для линукс

Since its name starts with “git-”, we can use the simple syntax for the configuration value:

As you can see, extending this system is pretty straightforward, and can solve some common problems for you and your team.

7.14 Инструменты Git — Хранилище учётных данных

Хранилище учётных данных

Если для подключения к удалённым серверам вы используете SSH-транспорт, то вы можете использовать ключ без пароля, что позволит вам безопасно передавать данные без ввода логина и пароля. Однако, это невозможно при использовании HTTP-протоколов — каждое подключение требует пары логин, пароль. Всё ещё сложнее для систем с двухфакторной аутентификацией, когда выражение, которое вы используете в качестве пароля, генерируется случайно и его сложно воспроизвести.

К счастью, в Git есть система управления учётными данными, которая может помочь в этом. В Git «из коробки» есть несколько опций:

По умолчанию Git не кеширует учётные данные совсем. Каждое подключение будет запрашивать у вас логин и пароль.

В режиме «cache» учётные данные сохраняются в памяти в течение определённого периода времени. Ни один из паролей никогда не сохраняется на диск и все они удаляются из кеша через 15 минут.

В режиме «store» учётные данные сохраняются на неограниченное время в открытом виде в файле на диске. Это значит что, до тех пор пока вы не измените пароль к Git-серверу, вам не потребуется больше вводить ваши учётные данные. Недостатком такого подхода является то, что ваш пароль хранится в открытом виде в файле в вашем домашнем каталоге.

На случай если вы используете Mac, в Git есть режим «osxkeychain», при использовании которого учётные данные хранятся в защищённом хранилище, привязанному к вашему системному аккаунту. В этом режиме учётные данные сохраняются на диск на неограниченное время, но они шифруются с использованием той же системы, с помощью которой сохраняются HTTPS-сертификаты и автозаполнения для Safari.

В случае если вы используете Windows, вы можете установить помощник, называемый «winstore». Он похож на «osxkeychain», описанный выше, но для управления секретной информацией использует Windows Credential Store. Найти его можно по ссылке https://gitcredentialstore.codeplex.com.

Мы можете выбрать один из этих методов, изменив настройки Git:

Некоторые из этих помощников имеют опции. Помощник «store» может принимать аргумент —file

, который определяет где будет хранится файл с открытыми учётными данный (по умолчанию используется

/.git-credentials ). Помощник «cache» принимает опцию —timeout , которая изменяет промежуток времени, в течение которого демон остаётся запущенным (по умолчанию «900», или 15 минут). Ниже приведён пример как вы можете настроить помощник «store» на использование определённого файла:

Git позволяет настраивать сразу несколько помощников. При поиске учётных данных для конкретного сервера, Git будет по порядку запрашивать у них учётные данные и остановится при получении первого ответа. При сохранении учётных данных, Git отправит их всем помощникам в списке, которые уже в свою очередь могут решить, что с этими данными делать. Ниже приведено как будет выглядеть .gitconfig , если у вас есть файл с учётными данными на флэш-диске, но, на случай его отсутствия, вы хотите дополнительно использовать кеширование в оперативной памяти.

Под капотом

Как же это всё работает? Корневой командой Git для системы помощников авторизации является git credential , которая принимает команду через аргумент, а все остальные входные данные через стандартный поток ввода.

Возможно, это проще понять на примере. Допустим, помощник авторизации был настроен и в нем сохранены учётные данные для mygithost . Ниже приведена рабочая сессия, в которой используется команда «fill», вызываемая Git при попытке найти учётные данные для сервера:

Это команда, которая начинает взаимодействие.

После этого Git-credential ожидает данные из стандартного потока ввода. Мы передаём ему то, что знаем: протокол и имя сервера.

Пустая строка обозначает, что ввод закончен и система управления учётными данными должна ответить, что ей известно.

После этого Git-credential выполняет какую-то работу и выводит обнаруженную информацию.

Если учётные данные не найдены, Git спрашивает у пользователя логин/пароль, и выводит их обратно в задействованный поток вывода (в данном примере это одна и та же консоль).

Читайте также:  Установка dns сервер windows 2003

В действительности, система управления учётными данными вызывает программы, отделённые от самого Git; какие и как зависит в том числе и от настроек credential.helper . Существует несколько вариантов вызова:

Выполняется git-credential-foo -a —opt=bcd

Выполняется /absolute/path/foo -xyz

Код после символа ! выполняется в шелле

Итак, помощники, описанные выше на самом деле называются git-credential-cache , git-credential-store и т. д. и мы можем настроить их на приём аргументов командной строки. Общая форма для этого git-credential-foo [args] . Протокол ввода/вывода такой же как и у git-credential, но они используют немного другой набор операций:

get запрос логина и пароля.

store запрос на сохранение учётных данных в памяти помощника.

erase удаляет учётные данные для заданных параметров из памяти используемого помощника.

Для операций store и erase не требуется ответа (в любом случае Git его игнорирует). Однако, для Git очень важно, что помощник ответит на операцию get . Если помощник не знает что-либо полезного, он может просто завершить работу не выводя ничего, но если знает — он должен добавить к введённой информации имеющуюся у него информацию. Вывод обрабатывается как набор операций присваивания; выведенные значения заменят те, что Git знал до этого.

Ниже приведён пример, используемый ранее, но вместо git-credential напрямую вызывается git-credential-store:

Здесь мы просим git-credential-store сохранить некоторые учётные данные: логин «bob» и пароль «s3cre7», которые будут использоваться при доступе к https://mygithost .

Теперь мы извлечём эти учётные данные. Мы передаём часть уже известных нам параметров подключения ( https://mygithost ) и пустую строку.

git-credential-store возвращает логин и пароль, которые мы сохранили ранее.

Ниже приведено содержимое файла

Это просто набор строк, каждая из которых содержит URL, включающий в себя учётные данные. Помощники osxkeychain и winstore используют форматы, лежащие в основе их хранилищ, а cache использует его собственный формат хранения во внутренней памяти (который другие процессы прочитать не могут).

Собственное хранилище учётных данных

Поскольку git-credential-store и подобные ей утилиты являются отдельными от Git программами, не сложно сделать так, чтобы любая программа могла быть помощником авторизации Git. Помощники, предоставляемые Git, покрывают наиболее распространённые варианты использования, но не все. Для примера допустим, что ваша команда имеет некоторые учётные данные, совместно используемые всей командой, например, для развёртывания. Эти данные хранятся в общедоступном каталоге, но вы не хотите копировать их в ваше собственное хранилище учётных данных, так как они часто изменяются. Ни один из существующих помощников не покрывает этот случай; давайте посмотрим, что будет стоить написать свой собственный. Есть несколько ключевых особенностей, которым должна удовлетворять эта программа:

Мы должны уделить внимание только одной операции get ; store и erase являются операциями записи, поэтому мы не будем ничего делать при их получении.

Формат файла с совместно используемыми учётными данными такой же как и у git-credential-store .

Расположение это файла более-менее стандартное, но, на всякий случай, мы должны позволять пользователям передавать свой собственный путь.

Мы снова напишем расширение на Ruby, но подойдет любой язык, так как Git может использовать всё, что сможет запустить на выполнение. Ниже приведён полный исходный код нашего нового помощника авторизации:

Здесь мы разбираем аргументы командной строки, позволяя указывать пользователям входной файл. По умолчанию это

Эта программа отвечает только если операцией является get и файл хранилища существует.

В цикле считываются данные из стандартного ввода, до тех пор пока не будет прочитана пустая строка. Введённые данные для дальнейшего использования сохраняются в отображении known .

Этот цикл читает содержимое файла хранилища, выполняя поиск соответствия. Если протокол и сервер из known соответствуют текущей строке, программа выводит результат и завершает работу.

Мы сохраним нашего помощника как git-credential-read-only , поместим его в один из каталогов, содержащихся в списке PATH , а так же сделаем его исполняемым. Ниже приведено на что будет похож сеанс взаимодействия:

Так как его имя начинается с «git-», мы можем использовать простой синтаксис для настройки:

Как вы видите, расширять эту систему довольно просто и это позволяет решить некоторые общие проблемы, которые могут возникнуть у вас и вашей команды.

Оцените статью