Skip to content

Credentials and Signing

Credentials decide how Git authenticates to a remote (SSH keys or an HTTPS credential helper), and signing proves who authored a commit or tag. Interviewers ask about both because they are where security meets daily workflow: how a push is authorized, and how a commit's author can be trusted.

Track: Core · Interview weight: Med


Must-Know Facts

Fact Value Verify with
SSH auth Key pair; public key on the host, private key local ssh -T git@host
HTTPS auth A token via a credential helper, never a password git config credential.helper
Credential helper Caches or stores the token so it is not retyped git config credential.helper
macOS helper osxkeychain, built in git config credential.helper
Windows helper Git Credential Manager (manager) git config credential.helper
Commit signing gpg.format selects openpgp, ssh or x509 git config gpg.format
SSH signing Reuse an SSH key to sign commits (Git 2.34+) git log --show-signature
Sign a commit -S, or commit.gpgsign true for all git log --pretty=%G?
Verify Needs allowedSignersFile for SSH signatures git log --show-signature
Signature status %G? is G (good), B (bad), N (none) git log --pretty=%G?

SSH Versus HTTPS

A remote URL's scheme decides how Git authenticates. SSH (git@host:owner/repo.git) uses a key pair; HTTPS (https://host/owner/repo.git) uses a token supplied by a credential helper.

  • SSH: generate a key, add the public half to the host, and pushes authenticate with the private key. No per-push prompt, and no token to store on disk.
  • HTTPS: authenticate with a personal access token (never an account password), which a credential helper caches so it is entered once.

Both are valid; teams often prefer SSH for developer machines and HTTPS with a token for CI. The remote URL alone determines which path a given clone uses.


The Credential Helper (HTTPS)

For HTTPS remotes, a credential helper stores or caches the token so Git does not prompt on every push. The right helper depends on the platform.

git config --show-origin credential.helper

Output:

file:/Library/Developer/CommandLineTools/usr/share/git-core/gitconfig   osxkeychain

macOS ships osxkeychain, which keeps the token in the login keychain. On Linux, use libsecret (git config --global credential.helper libsecret) to store it in the desktop keyring, or cache to hold it in memory for a timeout.

git config --global credential.helper manager

Windows uses Git Credential Manager (manager), installed with Git for Windows, which stores the token in the Windows Credential Store and handles browser-based sign-in for hosted platforms.

An HTTPS remote takes a token, never your account password

Hosted platforms stopped accepting account passwords over HTTPS; a push prompts for a personal access token instead. Store it through the credential helper, scope it to the minimum, and treat it like a secret. Never paste a token into a URL or commit it to the repo.


Signing Commits With an SSH Key

Signing attaches a cryptographic proof of authorship. Since Git 2.34 an existing SSH key can sign, so no separate GPG key is needed. Three config keys turn it on.

git config gpg.format ssh
git config user.signingkey ~/.ssh/id_ed25519.pub
git config commit.gpgsign true

With commit.gpgsign true, every commit is signed; without it, sign one commit with git commit -S. Creating a commit now attaches a signature, though verifying it needs one more step.

git commit -m "feat: signed commit"
git log --show-signature -1

Output:

error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification
commit aca209a229e0b37228a92b6146ff493476c0c365
No signature

The commit is signed, but Git cannot verify an SSH signature without knowing which keys to trust.


Verifying a Signature

Verification needs an allowed-signers file: a list mapping an identity to its public key. Point gpg.ssh.allowedSignersFile at it, then verification succeeds.

printf 'amina@example.com %s\n' "$(cat ~/.ssh/id_ed25519.pub)" > ~/.ssh/allowed_signers
git config gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
git log --show-signature -1

Output:

commit aca209a229e0b37228a92b6146ff493476c0c365
Good "git" signature for amina@example.com with ED25519 key SHA256:aVq9VWtGDKm71xTRpSGwf8LmvXNaf75Py/3rUkM6rsA

Good ... signature confirms the commit was signed by a trusted key. The one-character status is quicker to script.

git log -1 --pretty='%h signature=%G? signer=%GS'

Output:

aca209a signature=G signer=amina@example.com

%G? returns G for a good signature, B for bad, U for unknown validity, and N for none.

Signing proves authorship; the host displays 'Verified'

A local Good signature means the key matches your allowed-signers file. Hosted platforms show a Verified badge only when the signing key is registered to the account as a signing key, which is a separate upload from an authentication key. Register the key on the platform for the badge to appear.


Common Errors

gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification

Cause: SSH signature verification has no list of trusted keys to check against.

Fix: create an allowed-signers file (email key) and set git config gpg.ssh.allowedSignersFile <path>.

git@github.com: Permission denied (publickey)

Cause: the SSH key is missing from the agent or not registered on the host, so key authentication fails.

Fix: add the key with ssh-add, confirm with ssh -T git@github.com, and register the public key on the host.


Interview Checkpoints

L1: What are the two ways Git authenticates to a remote, and how do they differ?

Say first: SSH with a key pair (public key on the host, private key local), or HTTPS with a personal access token supplied by a credential helper; the remote URL's scheme decides which is used.

Proof: an SSH remote is git@host:owner/repo.git; an HTTPS remote prompts for a token that credential.helper then stores.

Follow-up: Why does an HTTPS push ask for a token rather than a password?

L1: What does a credential helper do?

Say first: it caches or stores the HTTPS token so Git does not prompt on every operation, using the platform keychain (osxkeychain, libsecret, or Git Credential Manager on Windows).

Proof: git config credential.helper names the active helper.

Follow-up: Where does the token physically live for each helper?

L2: Turn on commit signing without setting up GPG.

Say first: use SSH signing (Git 2.34+): set gpg.format ssh, point user.signingkey at your public key, and enable commit.gpgsign.

Proof:

git config gpg.format ssh
git config user.signingkey ~/.ssh/id_ed25519.pub
git config commit.gpgsign true

Follow-up: What else is needed before git log --show-signature can verify it?

L2: A signed commit shows 'No signature' with an allowedSignersFile error. What is wrong?

Say first: the commit is signed, but SSH verification has no trusted-keys list; configure gpg.ssh.allowedSignersFile.

Proof:

git config gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
git log --show-signature -1   # now Good signature

Follow-up: What format does each line of that file take?

L2: How do you check in a script whether the tip commit is validly signed?

Say first: read %G?; G means a good signature.

Proof:

git log -1 --pretty=%G?   # G, B, U, or N

Follow-up: What do B and N mean?

L3: A commit signs and verifies locally but the platform still shows Unverified. Why, and how do you fix it?

Say first: local verification uses your allowed-signers file, but the platform badge requires the signing key to be registered to your account as a signing key, which is a separate upload from an auth key.

Proof: the same key added under the account's signing keys makes the badge appear; the commit content and signature are unchanged.

Follow-up: Why are authentication keys and signing keys tracked separately by the host?


Captured on macOS 26 with git 2.50.1 (throwaway local repositories), 2026-09.