In recent years, Git has seen a sharp rise in popularity over other SCM systems such as subversion.
With the rise of free platforms such as GitHub and GitLab, it’s easier than ever to securely version and save our application code.
But constantly typing in credentials can be cumbersome and hard to create automated CI/CD pipelines.
In this tutorial, we’ll look at how to configure Git credentials to prevent entering them manually.
2. Inputting Credentials
Whenever a remote connection requires authentication, Git has several ways to look for credentials to use.
Let’s start with the basics, in which no credentials have been configured. If Git needs a username and password to access a remote connection, it takes the following steps to prompt the user for input.
First, it tries to invoke an application that allows the users to input credentials. The following values are checked (in order) to determine the application to use:
- GIT_ASKPASS environment variable
- core.askPass configuration variable
- SSH_ASKPASS environment variable
Setting any of these invokes the application and the user’s input is read from its standard output
If none of these values are set, Git reverts to prompting the user for input on the command line.
3. Storing Credentials
Typing in usernames and passwords can be tedious, especially when committing code frequently throughout the day.
Manually typing passwords is error-prone and also makes it difficult to create automated pipelines.
To help with this, Git provides several ways to store usernames and passwords. We’ll look at each way in the following sections.
3.1. Username and Password in URLs
Some Git providers allow embedding usernames and passwords together in the repository URL. This can be done when we clone the repository:
$ git clone https://<username>:<password>@gitlab.com/group/project.git
Let’s keep in mind that if the password has special characters, they will need to be escaped to prevent the shell from trying to interpret them.
Alternatively, we can edit the Git config file inside the repository to include the username and password:
url = https://<username>:<password>@<code class="language-shell">gitlab.com/group/project.git
Let’s also note that the username and password are stored in plain text, so anyone with access to the repository would be able to see them.
3.2. Credential Contexts
Git also allows configuring credentials per context. The following command will configure a specific Git context to use a specific username:
$ git config --global credential.https://github.com.username <your_username>
Alternatively, we can directly edit our global Git config file. This is typically found in our home directory in a file named .gitconfig, and we would add the following lines:
username = <username>
This method is also insecure because the username is stored in plain text. It also doesn’t allow storing passwords, so Git will continue to prompt them.
4. Credential Helpers
Git provides credential helpers to save credentials more securely. Credential helpers can store data in multiple ways and even integrate with 3rd party systems like password keychains.
Out of the box, Git offers 2 basic credential helpers. Cache, which stores credentials in memory for short durations, and Store which stores credentials indefinitely on disk.
Let’s cover each method in the next sections.
4.1. Cache Credential Helper
Here’s how we can configure the cache credential helper:
$ git config credential.helper cache
The cache credential helper never writes credentials to disk, although the credentials are accessible using Unix sockets. These sockets are protected using file permissions that are limited to the user who stored them, so generally speaking, they are secure.
We can also provide a timeout argument when configuring the cache credential helper. This allows us to control how long the credentials remain in memory:
$ git config credential.helper 'cache --timeout=86400'
This will save in memory credentials for 1 day after entering them.
4.2. Store Credential Helper
The store credential helper indefinitely saves credentials to a file.
We can configure the store credential helper:
$ git config credential.helper store
While the file contents are not encrypted, they are protected using file system access controls to the user that created the file.
By default, the file is stored in the user’s home directory. We can override the file location by passing a file argument to the command:
$ git config credential.helper 'store --file=/full/path/to/.git_credentials'
4.3. Custom Credential Helpers
Beyond the two default credential helpers above, it’s also possible to configure custom helpers.
These allow us to do more sophisticated credential management by delegating to 3rd party applications and services.
Creating custom credential helpers is not something most users will need to worry about.
However, there are several reasons they can be helpful:
- Integrate with Operating System tools such as Keychain on macOS
- Incorporate existing corporate authentication schemes such as LDAP or Active Directory
- Provide additional security mechanisms such as two-factor authentication
4.4. Removing Cached Credentials From Git
Git also allows us to easily delete any cached credentials. The Git credential cache runs a daemon process that caches our credentials in memory and hands them out on demand.
Let’s disable the use of the Git credential cache:
$ git config --global --unset credential.helper
We have the option of choosing between –global, –local, and –system options depending on our initial configuration level.
This command defaults to the local level if we don’t specify a configuration level.
5. SSH Keys
Most modern Git servers offer access to repositories using SSH keys instead of a username and a password over HTTPS.
SSH keys are harder to guess than a password and can easily be revoked if they become compromised.
The main downside to using SSH is that it uses non-standard ports. Some networks or proxies may block these ports, making communication with the remote server impossible.
They also require additional steps to set up SSH keys on both the server and client, which can be cumbersome in large organizations.
The easiest way to enable SSH for a Git repository is to use SSH for the protocol when cloning it:
$ git clone [email protected]:group/project.git
For an existing repository, we can update the remote with the following command:
$ git remote set-url origin [email protected]:group/project.git
The process for configuring SSH keys varies slightly for each Git server.
In general, it generates a compatible public/private key combination on the machine and uploads the public key to your Git server.
Most Unix/Linux users will already have an SSH key pair created and configured in their home directory and upload the existing public key. We should never upload or otherwise share our private key.
In this tutorial, we have seen various ways to configure Git credentials. The most common way is to use the built-in credential helper to store credentials locally in memory or a file on disk.
A more sophisticated and secure way to store credentials is by using SSH, although this can be more complex and may not work on all networks.