Git Credential Management

Last update: 2025-10-07 11:26:05 +0800 +0800
tags: Git | Security
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Git delegates HTTP(S) authentication to credential helpers. SSH remotes use SSH keys and agents instead, so credential.helper does not manage their private keys.

Select a Credential Helper #

List configured helpers together with the configuration file that set them:

sh
git config --show-origin --get-all credential.helper
git help -a | grep credential-

Git asks helpers in configured order to fill missing credential fields. A helper can decline or return partial data, after which Git may query another helper or prompt the user.

HelperStorageSuitable Use
cacheMemory in a local daemonShort-lived development sessions
storePlaintext ~/.git-credentialsOnly where plaintext storage is an accepted risk
osxkeychainmacOS KeychainmacOS development
Git Credential ManagerPlatform secure storage and browser sign-inSupported desktop platforms

For example, use a bounded in-memory cache:

sh
git config --global credential.helper 'cache --timeout=3600'

Prefer a platform keychain or Git Credential Manager over store. A local repository can override the global helper by omitting --global.

Scope Tokens and Usernames #

Git matches a credential by protocol and host unless path matching is enabled. When accounts or tokens differ by repository, include the HTTP path:

sh
git config --global credential.useHttpPath true

Credential sections can prefill a username without storing a secret:

ini
[credential "https://github.com"]
    username = octo

Do not embed a token in a remote URL. Git configuration, process arguments, terminal history, debug output, and copied logs can expose such URLs.

Use GitHub Tokens Safely #

GitHub removed password authentication for Git operations over HTTPS in 2021. Enter a personal access token in the password prompt, or allow a credential helper or Git Credential Manager to supply it.

Fine-grained tokens restrict access to selected resources and permissions. Choose them when their resource model covers the required operation. Classic tokens remain necessary for integrations that require permissions unavailable to fine-grained tokens. In either case:

  1. grant the smallest repository and permission scope;
  2. set an expiration date;
  3. keep the value in an operating-system keychain, a secret manager, or CI secret storage;
  4. revoke and replace a token exposed in a log or shell history.

SSH avoids HTTP credential helpers. If outbound port 22 is blocked, a hosting provider may support SSH on port 443; configure that endpoint only after verifying the provider’s published instructions and host key fingerprint.

Control Interactive Prompts #

When helpers cannot provide a credential, Git checks GIT_ASKPASS, core.askPass, and then SSH_ASKPASS. The selected program receives a prompt as an argument and writes an answer to standard output. Without a suitable askpass program, Git prompts on the controlling terminal.

Automation should receive a short-lived, scoped token from a CI secret store. Set GIT_TERMINAL_PROMPT=0 when a non-interactive job must fail rather than hang waiting for a prompt:

sh
GIT_TERMINAL_PROMPT=0 git fetch origin

Never put a token in a repository, Docker image layer, test fixture, or command line that a process listing can reveal.

Inspect, Reject, and Rotate Credentials #

git credential is plumbing for communicating with configured helpers using blank-line-delimited key-value records:

sh
printf 'protocol=https\nhost=example.com\n\n' | git credential fill
printf 'protocol=https\nhost=example.com\nusername=octo\n\n' |
  git credential reject

fill requests a credential, approve asks helpers to save one, and reject asks them to remove a rejected credential. A helper controls the exact storage and removal behavior. Keychain applications also provide a graphical way to inspect and delete entries.

After revoking or rotating a token, remove its old helper entry before retrying the operation. Otherwise Git can continue submitting the stale credential and obscure a successful replacement.

Comments

Read or comment on GitHub (sign-in required to comment)