SSH Keys and Git Authentication
Git remotes need to know who you are. You authenticate either with an SSH key pair, where the private key stays on your machine and the public key is registered with the server, or with an access token over HTTPS.
SSH keys
A key pair has two parts. The private key proves your identity and must never leave your machine. The public key can be shared freely and is registered in your account on the Git host.
ssh-keygen -t ed25519 -C "you@example.com" # creates id_ed25519 and id_ed25519.pub in ~/.ssh
ssh-add ~/.ssh/id_ed25519 # load the key into the SSH agent
ssh -T git@github.com # test the connection
- Protect the key with a passphrase when
ssh-keygenasks. - Add the contents of the
.pubfile in your account settings on the Git host. - Use the SSH form of the remote URL, for example
git@github.com:org/repo.git.
Windows 10 and later include the OpenSSH client. The ssh-agent service is disabled by default and has to be enabled once, in a PowerShell window started as administrator. After that, ssh-add works as a normal user:
Get-Service ssh-agent | Set-Service -StartupType Manual
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
ssh-add -l # list loaded keys
Git Bash also works. A first ssh -T git@github.com asks you to confirm the host fingerprint; answering yes saves it. A successful test greets you by username.
HTTPS and tokens
With a URL such as https://github.com/org/repo.git, most hosts no longer accept your account password. You use a personal access token instead. The Git Credential Manager, installed with Git for Windows, signs you in through the browser and stores the token securely.
- Give tokens the smallest set of permissions they need, and an expiry date.
- Treat a token like a password. Never paste it into code, chat or a commit.
Troubleshooting
Permission denied (publickey): the key is not loaded, not registered, or registered on a different account.- Check the remote URL with
git remote -v, and change it withgit remote set-url origin <url>. - A prompt for a password over HTTPS usually means the token or stored credential has expired.
- A stale or wrong stored credential (an old token, or the wrong account) is reused silently until you remove it.
git config --get credential.helpershows which helper stores it; on Windows it is normallymanager. Remove the entry, for examplegit:https://github.com, under Credential Manager, Windows Credentials in Control Panel, or in Git Bash runprintf "protocol=https\nhost=github.com\n\n" | git credential reject. The nextgit pushorgit fetchasks you to sign in again.
Try it
Generate a key, register it with your Git host, and clone a repository over SSH. Then run git remote -v and compare the SSH and HTTPS forms of the URL.
Common mistakes
- Sharing or committing the private key or a token.
- Registering the key on a different account than the one that owns the repository.
- Using an SSH key without a passphrase.
Check yourself
- Which of the two keys do you give to the Git host?
- What does Permission denied (publickey) usually mean?