Generate a key
Skip this if you already have one, which you can see with ls ~/.ssh/*.pub.
ssh-keygen -t ed25519 -C "you@example.com"
Accept the default file and set a passphrase. On Windows, see generating a key on Windows.
Not sure which type to pick? See RSA vs ed25519 SSH keys.
Copy the public key
pbcopy < ~/.ssh/id_ed25519.pub # macOS
cat ~/.ssh/id_ed25519.pub # Linux: copy the output by hand
On Windows, use Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard. It is one line starting with ssh-ed25519. If what you have starts with -----BEGIN, that is the private key, so stop and do not paste it anywhere.
Add it on GitHub
- Click your profile picture at the top right, then Settings.
- In the Access section of the sidebar, click SSH and GPG keys.
- Click New SSH key.
- Give it a title that names the machine, such as "Personal laptop".
- Choose the key type Authentication. Signing is a separate use: to sign commits with the same key, upload it a second time as Signing.
- Paste the key without adding line breaks, and click Add SSH key.
With GitHub's command line tool, after gh auth login:
gh ssh-key add ~/.ssh/id_ed25519.pub --title "Personal laptop"
GitHub no longer accepts DSA keys. If an organization you belong to uses SAML single sign-on, you may also have to authorize the key for it on the same page.
Test it, and check the fingerprint
ssh -T git@github.com
The first time, ssh asks whether to trust the host. Compare what it shows with the list GitHub publishes. We checked that these values match what github.com sends:
| Type | SHA256 fingerprint |
|---|---|
| Ed25519 | SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU |
| ECDSA | SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM |
| RSA | SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s |
GitHub can change these, so its own page is the reference. A successful login prints:
Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.
If you get an error instead, see git@github.com: Permission denied (publickey).
Why ssh asks the first time, and how to read the prompt: known_hosts and host fingerprints explained.
Make your repository use SSH
A key does nothing for a repository cloned over HTTPS. Check, and switch if needed:
git remote -v
git remote set-url origin git@github.com:OWNER/REPO.git
For a new clone, use the same form of address:
git clone git@github.com:OWNER/REPO.git
If Git asks for the passphrase or picks the wrong key
Load the key into ssh-agent once per session with ssh-add ~/.ssh/id_ed25519. On a Mac, the Keychain can keep the passphrase across restarts: see ssh-agent and the macOS Keychain.
If your key has another name, tell ssh which one to use for GitHub in ~/.ssh/config:
Host github.com
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
For a second GitHub account on the same machine, see multiple GitHub accounts with SSH.
If port 22 is blocked
Some networks block it, which shows up as a timeout. GitHub also accepts SSH on port 443:
ssh -T -p 443 git@ssh.github.com
If that works, make it permanent in ~/.ssh/config:
Host github.com
Hostname ssh.github.com
Port 443
User git
Questions
Why does ssh -T git@github.com exit with an error code?
It exits with code 1 even on success, because GitHub does not provide a shell. What counts is the Hi USERNAME message.
Can I use the same key on two GitHub accounts?
No. GitHub identifies your account from the key, and refuses a key already in use with Key already in use. See the guide on multiple GitHub accounts.
Why does Git ask for my SSH passphrase on every push?
Because the key is not loaded in ssh-agent. Run ssh-add ~/.ssh/id_ed25519 once per session. On a Mac, ssh-add --apple-use-keychain also saves the passphrase in the Keychain.
Sources
- Adding a new SSH key to your GitHub account, GitHub Docs
- Testing your SSH connection, GitHub Docs
- GitHub's SSH key fingerprints, GitHub Docs
- Using SSH over the HTTPS port, GitHub Docs