Managing Git credentials across hosts Jump to heading

Most developers authenticate to more than one Git host: the company’s forge, a public forge for open source, perhaps a self-hosted server for a client, and sometimes two accounts on the same host. Without deliberate configuration, Git asks for passwords repeatedly, stores tokens in plain text, or sends the wrong account’s token to a host β€” which fails confusingly or, worse, works and pushes under the wrong identity. Git’s credential system handles all of this through helpers configured per host. This page sets up a secure default helper, adds per-host helpers, separates multiple accounts on one host, and shows how to inspect and clear stored credentials, within Git configuration management at scale.

When to use this approach Jump to heading

  • Git prompts for credentials repeatedly over HTTPS.
  • Tokens are stored in a plain-text ~/.git-credentials file.
  • You have two accounts on the same host, such as personal and work.
  • You are standardising developer setup, as in bootstrapping a developer machine for Git.

Step 1 β€” See what is configured now Jump to heading

Credential helpers can be set in several configuration files, and Git runs all that apply. List them with their origin before changing anything.

git config --show-origin --get-all credential.helper
git config --show-origin --get-regexp '^credential\..*'
ls -la ~/.git-credentials 2>/dev/null && echo "plain-text credentials file exists"
How Git gets a credentialGit needs a credential for a host and asks each configured helper in turn. The first helper that has a matching entry returns it. If none does, Git prompts the user, and after the operation succeeds tells the helpers to store the credential. If authentication fails, Git tells the helpers to erase it.githelperuserserverget host=git.example.comnone storedprompttokenauthenticate200 OKstoreon a 401, git sends erase instead of store

Step 2 β€” Use the OS keychain as the default helper Jump to heading

Store credentials in the operating system’s encrypted store, not in a file. Git Credential Manager works across platforms; platform-specific helpers exist too.

# Cross-platform
git config --global credential.helper manager
# macOS keychain
git config --global credential.helper osxkeychain
# Linux with libsecret
git config --global credential.helper /usr/lib/git-core/git-credential-libsecret

⚠️ SAFETY WARNING: credential.helper store writes tokens to ~/.git-credentials in plain text. If it was used, move the tokens to a keychain helper, delete the file, and rotate any token that may have been copied or backed up along with it.

Step 3 β€” Configure per-host helpers Jump to heading

Helper settings can be scoped to a URL. Use this for hosts that need a different helper, such as a forge CLI that manages its own tokens, or a corporate host using single sign-on.

# ~/.gitconfig
[credential]
    helper = manager
[credential "https://github.com"]
    helper =
    helper = !gh auth git-credential
[credential "https://git.client.example"]
    username = jdoe

The empty helper = line resets the list for that host, so only the following helper runs there.

Step 4 β€” Separate two accounts on one host Jump to heading

By default, credentials are keyed on protocol and host, so two accounts on the same host overwrite each other. Including the path in the key lets each organisation or repository have its own credential.

git config --global credential.https://git.example.com.useHttpPath true
# Now credentials are stored per path: git.example.com/work-org/… and git.example.com/personal/…
Two accounts on one host β€” which approach?If accounts map to different organisations on the host, enable useHttpPath so credentials are stored per path. If you prefer SSH, use a separate key per account with host aliases. If accounts map to directories on your machine, combine includeIf with a per-directory username.How are the accounts separated?by organisation pathuseHttpPathper-path credentialsprefer SSHKey per accountHost alias in ssh configby local directoryincludeIfper-directory usernamethe commit identity is separate β€” set user.email per directory too

Step 5 β€” Or use SSH with per-account keys Jump to heading

SSH avoids token storage entirely. For multiple accounts on one host, use host aliases in the SSH configuration, each with its own key.

cat >> ~/.ssh/config <<'EOF'
Host github-work
    HostName github.com
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes
Host github-personal
    HostName github.com
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes
EOF
git clone git@github-work:work-org/service.git

URL rewriting can apply the alias automatically, as described in rewriting remote URLs with insteadOf.

Step 6 β€” Inspect and clear stored credentials Jump to heading

When a token expires or the wrong one is stored, ask Git which credential it would use, and erase it.

printf 'protocol=https\nhost=git.example.com\npath=work-org/service.git\n\n' | git credential fill   # shows what would be sent
printf 'protocol=https\nhost=git.example.com\n\n' | git credential reject                        # erase it from helpers

Be careful running fill on a shared screen; it prints the secret.

Step 7 β€” Set commit identity alongside credentials Jump to heading

Credentials decide who pushes; user.email decides who authored the commits. Set both per context, so work commits are not made with a personal email.

# ~/.gitconfig
[includeIf "gitdir:~/work/"]
    path = ~/.config/git/work.gitconfig
# ~/.config/git/work.gitconfig
[user]
    email = [email protected]
[credential "https://git.company.example"]
    username = jdoe
Credential storage optionsPlain-text store keeps tokens in a readable file and should not be used. OS keychain helpers encrypt tokens and integrate with the desktop. Forge CLI helpers reuse the CLI's login and refresh tokens. SSH keys avoid tokens entirely and can live in hardware or an agent.SecurityNotesstore (plain file)weakavoid; rotate if usedOS keychain / managerencryptedgood defaultforge CLI helperencryptedrefreshes tokensSSH keyno token at allagent or hardware keypick one default and per-host exceptions β€” not a different scheme per repository

Validation checklist Jump to heading

Frequently Asked Questions Jump to heading

Why does Git still prompt after I set a helper? Jump to heading

Another configuration file may set a helper later in the list, or a host-specific section resets it. git config --show-origin --get-all credential.helper shows every value in effect.

Do credential helpers affect SSH remotes? Jump to heading

No. SSH remotes use SSH keys and the SSH agent. Credential helpers apply only to HTTPS remotes.

How do CI jobs handle credentials? Jump to heading

Through short-lived tokens injected by the pipeline, not helpers on disk. See scoping deploy keys and tokens.

What should we standardise for the whole team? Jump to heading

One default helper per operating system, the per-host exceptions your forges need, and a rule that plain-text storage is never used. Put them in the shared team configuration so new machines get them from the start.

How do I know which account pushed? Jump to heading

The forge records the authenticated account for each push, separately from commit authors. Check the push or audit log if a push appears under an unexpected account.