Learn how SSH keys work, how to generate them, add them to remote servers and GitHub, and manage multiple keys across different services.
SSH (Secure Shell) keys are a pair of cryptographic keys used for authentication. Instead of typing a password every time you connect to a server or push to GitHub, your machine proves its identity using a private key — and the server verifies it with the matching public key.
The pair:
~/.ssh/id_ed25519) — stays on your machine. Never share it.~/.ssh/id_ed25519.pub) — goes on the server. Safe to share.When you connect, your client signs a challenge with the private key. The server verifies the signature with the public key. No password needed.
Modern systems should use Ed25519 (faster and more secure than RSA):
ssh-keygen -t ed25519 -C "your_email@example.com"
The -C flag adds a comment (usually your email) to identify the key.
Prompts:
Enter file in which to save the key (/home/you/.ssh/id_ed25519): [Press Enter]
Enter passphrase (empty for no passphrase): [Enter a strong passphrase]
Enter same passphrase again: [Repeat it]
Use a passphrase. It encrypts your private key on disk — if your machine is compromised, the attacker still can't use the key without the passphrase. You won't need to type it every time if you use ssh-agent (covered below).
This creates two files:
~/.ssh/id_ed25519 ← private key (never share)
~/.ssh/id_ed25519.pub ← public key (copy this to servers)
Legacy RSA (use only if Ed25519 isn't supported):
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Method 1: ssh-copy-id (easiest)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip
# Enter your password one last time
# From now on, no password needed
Method 2: Manual
# View your public key
cat ~/.ssh/id_ed25519.pub
# On the server, append it to authorized_keys
echo "your-public-key-content" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
Test the connection:
ssh user@server-ip
# Should connect without asking for a password
# macOS
cat ~/.ssh/id_ed25519.pub | pbcopy
# Linux
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard
# Or just print and copy manually
cat ~/.ssh/id_ed25519.pub
Go to GitHub → Settings → SSH and GPG keys → New SSH key
Give it a title (e.g., "MacBook Pro 2024"), paste the public key, save
Test:
ssh -T git@github.com
# Hi username! You've successfully authenticated...
Now use SSH URLs instead of HTTPS for your repos:
git clone git@github.com:username/repo.git
# Instead of: git clone https://github.com/username/repo.git
ssh-agent holds your decrypted key in memory so you only type the passphrase once per session.
# Start the agent
eval "$(ssh-agent -s)"
# Add your key (prompts for passphrase once)
ssh-add ~/.ssh/id_ed25519
# List added keys
ssh-add -l
macOS — persist across reboots by adding to ~/.ssh/config:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Then:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
When you have multiple keys for different services, use the SSH config file to keep things organized:
# ~/.ssh/config
# Personal GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
# Work GitHub
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
# Production server
Host prod
HostName 203.0.113.10
User ubuntu
IdentityFile ~/.ssh/id_ed25519_prod
Port 2222
# Staging server
Host staging
HostName 203.0.113.20
User ubuntu
IdentityFile ~/.ssh/id_ed25519_staging
Now you can connect with shortcuts:
ssh prod # instead of: ssh -i ~/.ssh/id_ed25519_prod -p 2222 ubuntu@203.0.113.10
ssh staging
# For work GitHub repos
git clone git@github-work:company/repo.git
Always use a passphrase on your private key. A key without a passphrase is as risky as a password written on a sticky note.
Set correct file permissions:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519 # private key — owner read/write only
chmod 644 ~/.ssh/id_ed25519.pub # public key
chmod 600 ~/.ssh/authorized_keys # on the server
chmod 600 ~/.ssh/config
Disable password authentication on servers once SSH keys are working:
# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
sudo systemctl restart sshd
Use different keys for different services — don't reuse one key everywhere. If one service is compromised, the others aren't affected.
Rotate keys periodically — especially when a team member leaves.
Permission denied (publickey):
ssh -v user@server # verbose output shows exactly where auth fails
Check that authorized_keys has the right permissions (600) and the key is exactly one line.
Key not being offered:
ssh-add -l # check if key is loaded in agent
ssh-add ~/.ssh/id_ed25519 # add it
SSH keys eliminate passwords from your workflow entirely — more secure and more convenient. Generate an Ed25519 key, add a passphrase, configure ssh-agent to avoid typing it repeatedly, and use ~/.ssh/config to manage multiple identities cleanly. Once set up, you'll wonder how you ever worked without them.