Managing credentials securely and conveniently
Anyone pushing over HTTPS knows the constant password prompt. Credential helpers solve that, but they differ significantly in security, persistence, and platform support.
Table of Contents
- 1. Why HTTPS remotes are annoying without a helper
- 2. The built in cache helper
- 3. The store helper and its risks
- 4. OS keychains as a secure alternative
- 5. Git Credential Manager as a cross platform solution
- 6. Combining multiple helpers and setting priority
- 7. Different helpers per host
- 8. Personal access tokens instead of passwords
- 9. Debugging credential helpers
- 10. Summary
- 11. FAQ
1. Why HTTPS remotes are annoying without a helper
Anyone accessing a remote repository over HTTPS instead of SSH has to authenticate on every operation that talks to the server. Without stored credentials, Git prompts for a username and token on every push, pull, or fetch.
That is not just tedious, it also tempts people to embed credentials directly in the remote URL, for example https://user:token@host/repo.git. Such URLs end up in plain text inside .git/config and in shell history, which is a real security risk.
A credential helper solves both problems at once: it stores credentials in a defined location and automatically hands them back to Git when needed, without them ever showing up in plain text in the configuration.
# Without a helper: a password prompt on every network operation
git push origin main
# Username for 'https://github.com': ...
# Password for 'https://user@github.com': ...
# Show the currently configured helper
git config --get-all credential.helper
2. The built in cache helper
The simplest helper is cache. It keeps credentials in memory for a limited time, served by a small background process called credential-cache--daemon. The default validity period is 900 seconds.
The big advantage: nothing is written to disk permanently. After a restart or once the timeout expires, the data is gone. For a short work session with several pushes in a row, that is entirely sufficient.
The downside is the limited lifetime: anyone who pauses longer than the configured timeout has to authenticate again. For developers working on the same repository all day, that quickly becomes too short.
# Enable cache with the default timeout
git config --global credential.helper cache
# Extend the timeout to four hours
git config --global credential.helper 'cache --timeout=14400'
# Clear the cache manually
git credential-cache exit
3. The store helper and its risks
The store helper writes credentials permanently and in plain text to a file, by default ~/.git-credentials. That fully solves the cache helper's timeout problem, since the data stays until explicitly removed.
That is exactly the problem, though: every process and every user with read access to that file can read the credentials in plain text. On a shared machine or a compromised system, this is a significant risk.
In practice, store should only be used on clearly secured single user systems, and even then an encryption layer is the better path. On every major desktop operating system there are better alternatives available.
# Enable store (plain text file, use with caution)
git config --global credential.helper store
# The file contains lines like:
# https://user:token@github.com
# Check file permissions, should be 600
ls -la ~/.git-credentials
4. OS keychains as a secure alternative
Every major operating system ships its own encrypted keychain that Git can use as a backend. On macOS that is osxkeychain, on Windows the Credential Manager via wincred, and on Linux libsecret, which connects to GNOME Keyring or KWallet.
These helpers store credentials in an encrypted form and bind them to the operating system user account. Access is only possible through the corresponding system APIs, not by simply reading a text file.
The downside: on Linux, libsecret often has to be compiled or installed separately, since it is not bundled with every Git distribution. On macOS and Windows the integration works right out of the box.
# macOS
git config --global credential.helper osxkeychain
# Windows (Git for Windows already ships manager-core)
git config --global credential.helper wincred
# Linux, after installing libsecret
sudo apt install libsecret-1-0 libsecret-1-dev
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
5. Git Credential Manager as a cross platform solution
Git Credential Manager, GCM for short, is a standalone project maintained by Microsoft that offers the same experience across all three major operating systems. Besides classic credentials, it also supports OAuth flows for GitHub, GitLab, Bitbucket, and Azure DevOps.
Instead of manually typing a username and password, GCM opens a browser window for sign in when needed and then stores a secure token in the respective OS keychain in the background. That combines convenience with the security level of native keychains.
For teams working across macOS, Windows, and Linux, GCM significantly reduces configuration effort, since a single solution delivers the same commands and the same behavior on every platform.
# Register GCM as the helper (after installing the package)
git config --global credential.helper manager
# Sign in to GitHub, opens the browser for OAuth
git push origin main
# A browser window opens automatically for sign in
6. Combining multiple helpers and setting priority
Git allows configuring multiple credential.helper entries at the same time. They are queried in order until one of them returns valid credentials. New or updated credentials are forwarded to all configured helpers simultaneously.
A common combination is a fast cache helper for short term repeats within a session, alongside a persistent keychain helper for long term storage. That way, even the brief access to the system keychain is skipped for every single operation.
It is important to understand the ordering: an empty credential.helper value first clears all previously set helpers from earlier configuration levels before new ones are defined. This is often overlooked when global and local configuration are combined.
# Combine two helpers: fast cache plus persistent keychain
git config --global --unset-all credential.helper
git config --global --add credential.helper cache
git config --global --add credential.helper osxkeychain
# Show active helpers in the correct order
git config --get-all credential.helper
7. Different helpers per host
In projects with multiple Git hosts, for example an internal GitLab alongside GitHub for open source contributions, helpers can be configured per URL. That prevents a token from accidentally being used against the wrong service.
Configuration works through credential.<url>.helper, where the URL can restrict the host or even a path. Combined with includeIf, entire configuration blocks can be loaded depending on the working directory, for example separate identities for company and personal repositories.
This granularity pays off especially in teams where developers work on multiple client projects, each with its own Git server. A misassigned token simply does not become an error source in the first place.
# Dedicated helper for a specific host only
git config --global credential.https://gitlab.internal.example.com.helper store
git config --global credential.https://github.com.helper osxkeychain
# includeIf for directory based configuration
[includeIf "gitdir:~/projects/client-a/"]
path = ~/.gitconfig-client-a
8. Personal access tokens instead of passwords
GitHub, GitLab, and Bitbucket now almost universally require personal access tokens instead of the account password for HTTPS access. Tokens can be created with a limited scope, expire after a set time, and be revoked individually at any point without changing the main password.
A compromised token causes far less damage than a compromised password, because it is only valid for the actions it was issued for. CI systems and automation should always use their own, narrowly scoped tokens.
Where possible, SSH with a dedicated key pair is still the more robust alternative to HTTPS tokens, since no credential helper is needed at all. In many corporate environments, though, SSH is blocked for firewall reasons, leaving HTTPS with a token as the only practical option.
# Enter a token instead of a password on first authentication
git push origin main
# Username: your-username
# Password: ghp_xxxxxxxxxxxxxxxxxxxx (Personal Access Token)
# Keep the token scope as narrow as possible, e.g. repo:status only
9. Debugging credential helpers
When Git keeps prompting for credentials despite a configured helper, the built in diagnostic environment variable helps. It shows exactly which helpers are called in which order and what they return.
Another useful tool is git credential fill, which tests the helper mechanism in isolation from an actual network operation. That makes it quick to determine whether the problem lies with the helper itself or with the actual server side authentication.
Common causes are stale tokens still stored in the keychain after a password or token change, as well as conflicting configuration at the global and repository level overwriting each other.
# Detailed tracing of the credential lookup
GIT_TRACE=1 git push origin main
# Test the helper in isolation
echo -e "protocol=https\nhost=github.com" | git credential fill
# Remove a stale entry from the macOS keychain
git credential-osxkeychain erase <<< "protocol=https
host=github.com"
| Helper | Persistence | Security | Platform |
|---|---|---|---|
| cache | In memory only, timeout based | No plain text on disk | All platforms |
| store | Permanent in a file | Plain text, low security | All platforms |
| osxkeychain / wincred | Permanent in the OS keychain | Encrypted, high | macOS / Windows |
| libsecret | Permanent in the OS keychain | Encrypted, high | Linux |
| Git Credential Manager | Permanent, token via OAuth | Encrypted, high | macOS, Windows, Linux |
Mironsoft
Git workflows, branching strategies, and CI hooks
Chaotic Git history and unclear branching rules across the team?
We set up clean Git workflows, clarify branching strategies for the team, and automate quality checks via Git hooks and CI pipelines so the history stays traceable.
Workflow Audit
Review the existing branching strategy and merge practice for weak spots.
Hook Automation
Set up pre-commit and pre-push hooks for linting, tests, and commit conventions.
Team Training
Teach rebase, cherry-pick, and conflict resolution hands-on across the team.
10. Summary
Credential Helpers
Recommendation
OS keychain or Git Credential Manager instead of store
Timeout
cache defaults to 900 seconds
Security risk
store keeps credentials in plain text
Debugging
GIT_TRACE=1 reveals the helper chain