DevPlainly
Developer Productivity

SSH Keys Explained: Generate, Add and Use Them Safely

Create an SSH key with ssh-keygen, add it to a server and to GitHub, use ssh-agent and a config file, and fix the most common SSH permission errors.

· 6 min read

Contents
  1. How SSH keys work in one minute
  2. Step 1: Check for an existing key
  3. Step 2: Generate a new key
  4. Step 3: Add your public key to a server
  5. Step 4: Add your key to GitHub (or GitLab)
  6. Step 5: Use ssh-agent so you type the passphrase once
  7. Step 6: Save time with ~/.ssh/config
  8. Using different keys for work and personal accounts
  9. Step 7: Disable password logins on your server
  10. Fixing common SSH errors
  11. Best practices
  12. FAQ
  13. Ed25519 or RSA?
  14. Can I use the same key for multiple servers?
  15. I forgot my key's passphrase. Can I recover it?
  16. Is it safe to share my public key?
  17. Further reading

SSH keys let you log in to servers and push to Git hosts without typing a password — and they are far more secure than passwords. This guide covers how they work, how to create one, how to install it on a server and on GitHub, and how to fix the errors everyone hits along the way.

The commands work on Linux, macOS and Windows 10/11, which ship with OpenSSH built in.

How SSH keys work in one minute

An SSH key is a pair of files:

  • Private key (for example ~/.ssh/id_ed25519): stays on your computer. Never share it, never upload it, never commit it.
  • Public key (~/.ssh/id_ed25519.pub): safe to share. You copy it to every server or service you want to access.

When you connect, the server uses your public key to send a challenge that only the matching private key can answer. Your private key never leaves your machine, so there is no password for an attacker to intercept or guess.

Step 1: Check for an existing key

ls -l ~/.ssh

If you see id_ed25519 and id_ed25519.pub (or id_rsa and id_rsa.pub), you already have a key and can skip to step 3. On Windows PowerShell, use ls $env:USERPROFILE\.ssh.

Step 2: Generate a new key

ssh-keygen -t ed25519 -C "you@example.com"
  • -t ed25519 picks the Ed25519 algorithm: modern, fast, with short keys. It is the recommended default today.
  • -C adds a comment (usually your email or machine name) to help you identify the key later.

Press Enter to accept the default location, then set a passphrase. The passphrase encrypts the private key on disk, so a stolen laptop or backup does not give away access. With ssh-agent (step 5) you only type it once per session.

If you need to connect to an old system that does not support Ed25519, generate an RSA key instead:

ssh-keygen -t rsa -b 4096 -C "you@example.com"

Step 3: Add your public key to a server

The easiest way on Linux and macOS:

ssh-copy-id user@203.0.113.10

It appends your public key to ~/.ssh/authorized_keys on the server and sets the right permissions.

Windows does not include ssh-copy-id. In PowerShell, this does the same:

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@203.0.113.10 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"

Now test it:

ssh user@203.0.113.10

If you are asked for your key passphrase (not the server password), it worked.

Step 4: Add your key to GitHub (or GitLab)

Print the public key and copy it:

cat ~/.ssh/id_ed25519.pub

On GitHub, go to Settings → SSH and GPG keys → New SSH key, paste it and save. GitLab and Bitbucket have equivalent pages in their user settings.

Test the connection:

ssh -T git@github.com

A message greeting you by username means it works. Then clone with the SSH URL:

git clone git@github.com:user/repo.git

To switch an existing repository from HTTPS to SSH:

git remote set-url origin git@github.com:user/repo.git

Step 5: Use ssh-agent so you type the passphrase once

The agent keeps your decrypted key in memory for the session.

Linux:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

macOS (stores the passphrase in the Keychain):

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Windows (PowerShell as Administrator, once):

Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Step 6: Save time with ~/.ssh/config

Instead of typing ssh deploy@203.0.113.10 -p 2222 -i ~/.ssh/work_key every time, create ~/.ssh/config:

Host myserver
    HostName 203.0.113.10
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Host github.com
    User git
    IdentityFile ~/.ssh/id_ed25519
    AddKeysToAgent yes

Now ssh myserver is all you need, and tools like scp, rsync and Git use the same settings:

scp backup.tar.gz myserver:/tmp/
rsync -av ./site/ myserver:/var/www/site/

Using different keys for work and personal accounts

Host github-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

Clone work repositories with git clone git@github-work:company/repo.git, and Git will use the work key.

Step 7: Disable password logins on your server

Once key login works — test it in a second terminal first — turn off password authentication so bots cannot brute-force it. Edit /etc/ssh/sshd_config on the server:

PasswordAuthentication no
PermitRootLogin prohibit-password

Then reload SSH:

sudo systemctl reload ssh     # Ubuntu/Debian (the service may be called sshd on other distros)

Keep your current session open until you have confirmed a new login works. Our VPS security checklist covers the rest of a server's first-day hardening.

Fixing common SSH errors

ErrorCauseFix
Permission denied (publickey)Server does not have your public key, or SSH is offering a different keyRe-run step 3; check with ssh -v user@host which keys are tried
UNPROTECTED PRIVATE KEY FILE!Private key permissions too openchmod 600 ~/.ssh/id_ed25519
Key ignored on the serverWrong permissions on the server's .sshchmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys
REMOTE HOST IDENTIFICATION HAS CHANGED!Server was reinstalled — or something is intercepting the connectionConfirm the server really changed, then ssh-keygen -R hostname
Too many authentication failuresAgent offers many keys before the right oneAdd IdentitiesOnly yes and IdentityFile in ~/.ssh/config

The single most useful debugging tool is verbose mode:

ssh -v user@host      # add more v's (-vvv) for more detail

Best practices

  • One key per device, not one key copied to every laptop. If a device is lost, you remove just its public key.
  • Always use a passphrase on keys stored on laptops.
  • Never commit private keys to a repository. Add id_* patterns to your global gitignore if you keep keys in unusual places.
  • Review authorized_keys on your servers occasionally and remove keys you no longer use.
  • Back up your private key securely (for example in a password manager) or be ready to replace it.

FAQ

Ed25519 or RSA?

Ed25519 for anything modern. Use RSA with 4096 bits only for old systems that do not support Ed25519.

Can I use the same key for multiple servers?

Yes. The same public key can be added to as many servers and services as you like.

I forgot my key's passphrase. Can I recover it?

No. Generate a new key pair and replace the old public key everywhere you used it. If you remember it and just want to change it, use ssh-keygen -p -f ~/.ssh/id_ed25519.

Is it safe to share my public key?

Yes — that is its purpose. Only the private key (the file without .pub) must stay secret.

Further reading

Keep reading