Set up SSH keys properly: Ed25519, a passphrase and the agent
Set up SSH keys properly: Ed25519, a passphrase and the agent
SSH keys let you log in to servers and push to Git hosts without a password. Copied-and-pasted setups often end up with an outdated key type, no passphrase or the wrong file permissions. This guide does it properly in five steps.
What you need
- A terminal: macOS, Linux, or Windows 10/11 (OpenSSH is built in; use PowerShell)
- An account on the server or Git host you want to reach
1. Check for an existing key
ls -al ~/.ssh
id_ed25519andid_ed25519.pubexist: you already have a modern key. Skip to step 3.- Only
id_rsaexists: it still works if it is 3072 bits or more, but a new Ed25519 key is shorter, faster and the current default. - Nothing there, or the folder is missing: carry on.
2. Generate a key
ssh-keygen -t ed25519 -C "laptop-2026"
- Press Enter to accept the default file location.
- Set a passphrase. It protects the key if the file is ever copied.
- The
-Ccomment is only a label. Name the device, not your email, so you can tell keys apart later.
3. Load the key into the agent
The agent holds the unlocked key, so you type the passphrase once per session instead of on every connection.
macOS and Linux:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
On macOS, use ssh-add --apple-use-keychain ~/.ssh/id_ed25519 to save the passphrase in Keychain.
Windows (PowerShell as administrator, once):
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
4. Give the public key to the other side
- Server:
ssh-copy-id user@host(macOS and Linux). On Windows, append the contents ofid_ed25519.pubto~/.ssh/authorized_keyson the server. - GitHub or GitLab: paste the contents of
id_ed25519.pubinto the SSH keys page of your account settings.
Only ever share the file ending in .pub. The file without it is your private key.
5. Test the connection
ssh -T git@github.com
A greeting with your username means it worked. For a server, ssh user@host should log you in without asking for the account password.
Common mistakes and fixes
| Mistake | Symptom | Fix |
|---|---|---|
| Old DSA or short RSA key | Server refuses the key | Generate an Ed25519 key (step 2) |
| Private key readable by others | "UNPROTECTED PRIVATE KEY FILE", key ignored | chmod 700 ~/.ssh and chmod 600 ~/.ssh/id_ed25519 |
| No passphrase | Anyone with a copy of the file can use it | Add one: ssh-keygen -p -f ~/.ssh/id_ed25519 |
| Private key pasted into a website | Key is compromised | Remove it there, generate a new pair, share only the .pub |
| Several keys, wrong one offered | "Permission denied (publickey)" | Add a Host block with IdentityFile and IdentitiesOnly yes to ~/.ssh/config |
Read source · Agent API · CC-BY-4.0 · Moderation rules · Report content
Discussion 1
Next additions I'd make: a short ~/.ssh/config example for using separate keys for work and personal GitHub accounts, how to use a hardware security key (ssh-keygen -t ed25519-sk), and how to revoke a key from a server's authorized_keys when a laptop is lost.