Check for existing keys, create a key pair, load it into the agent, add it to GitHub, then clone a private repo over SSH. Verified on Ubuntu 22.04. For two GitHub accounts on one machine, continue with ssh-multiple-github-accounts.
The big picture
- Two linked files:
id_ed25519→ private, never shared ·id_ed25519.pub→ public, paste anywhere. - The private key never travels. GitHub sends a challenge only that key can answer.
- Why SSH over HTTPS: no token to type or renew, and multiple accounts work cleanly via host aliases.
1. Check for existing keys
ls -al ~/.sshid_ed25519,id_rsa→ private keys (keep secret)id_ed25519.pub,id_rsa.pub→ public keys (safe to share)config→ per-host SSH settings ·known_hosts→ servers you’ve connected toauthorized_keys→ keys allowed to SSH into this machine (unrelated to GitHub)
ls ~/.ssh/*.pub 2>/dev/null || echo "No public keys found" # public keys only
ssh-keygen -lf ~/.ssh/id_ed25519.pub # whose key is this? (see comment field)"Overwrite (y/n)?" means a key already exists
Answering
ydestroys it, and every server trusting it stops recognising you. Answernand pick another-ffilename.
2. Generate a key pair (ed25519)
ssh-keygen -t ed25519 -C "xuebin@Cygnus-2026-08-29" -f ~/.ssh/id_ed25519
# enter a passphrase when asked (twice)-t ed25519→ modern, short and strong. Use-t rsa -b 4096only for very old systems.-C→ a label only. Name the machine, so you know which key to revoke later.-f→ output path; avoids the overwrite prompt.- Passphrase: use one. The agent means you type it once per login. Change it later with
ssh-keygen -p -f ~/.ssh/id_ed25519.
3. Fix permissions
SSH refuses keys other users can read, with Bad owner or permissions, which looks like a key problem but isn’t.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 ~/.ssh/config
chmod 644 ~/.ssh/id_ed25519.pub
stat -c '%A %n' ~/.ssh ~/.ssh/id_ed25519 # expect drwx------ and -rw-------4. Load the key into the ssh-agent
The agent holds the unlocked key in memory, so the passphrase is typed once.
echo $SSH_AUTH_SOCK # set? an agent is already running (GNOME desktop)
ssh-add ~/.ssh/id_ed25519 # add the key, passphrase once
ssh-add -l # list loaded keysDon't run
eval "$(ssh-agent -s)"on a GNOME desktopIt starts a second agent that only exists in that terminal, so keys vanish when it closes. The classic cause of “it worked a minute ago”. Use it only on servers, WSL or a bare TTY, where
SSH_AUTH_SOCKis empty.
Load keys automatically on first use, in ~/.ssh/config:
Host *
AddKeysToAgent yes
5. Add the public key to GitHub
cat ~/.ssh/id_ed25519.pub # copy the whole line: ssh-ed25519 AAAA... labelGitHub → avatar → Settings → SSH and GPG keys → New SSH key:
- Title → the machine name · Key type → Authentication Key (not Signing Key, which silently won’t grant access)
- With several accounts, check which one you’re logged into first, or you’ll get “Repository not found” later.
6. Test the connection
ssh -T [email protected]
# Hi <user>! You've successfully authenticated, but GitHub does not provide shell access.- “does not provide shell access” → normal, not an error. The name after
Hi= which account you are. - First time only: check the host fingerprint before typing
yes. ED25519 should beSHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU(GitHub publishes the list). This is your only protection against an impostor server.
7. Clone a private repository
git clone [email protected]:OWNER/REPO.git
git remote -v # confirm the URL
git remote set-url origin [email protected]:OWNER/REPO.git # convert an existing HTTPS clonegit remote add→ creates a remote (fails iforiginexists) ·git remote set-url→ changes it.- Multiple accounts → use your host alias (
github-personal:OWNER/REPO.git), see ssh-multiple-github-accounts.
Troubleshooting
| Symptom | Likely cause | Check / fix |
|---|---|---|
Repository not found | private repo + key from an account without access, or a typo | ssh -T [email protected] (who am I?), git remote -v |
Permission denied (publickey) | no key loaded, or not on the account | ssh-add -l · ssh -vT [email protected] 2>&1 | grep -i offering |
Bad owner or permissions | permissions too open | redo step 3 |
| Asks for the passphrase again | key was in a throwaway agent | re-add it, set AddKeysToAgent yes |
| Authenticated as the wrong user | SSH offered another key first | host aliases + IdentitiesOnly yes, see ssh-multiple-github-accounts |
Quick reference
ls -al ~/.ssh # what keys exist
ssh-keygen -t ed25519 -C "label" -f ~/.ssh/id_ed25519 # generate
ssh-keygen -lf ~/.ssh/id_ed25519.pub # fingerprint
ssh-add ~/.ssh/id_ed25519 && ssh-add -l # load and list
cat ~/.ssh/id_ed25519.pub # the half you upload
ssh -T [email protected] # who am I?
ssh -vT [email protected] # ...verbosely
git remote set-url origin [email protected]:OWNER/REPO.git # HTTPS -> SSH