SSH keys are one of the most important things you can set up on a new machine, and one of the most consistently under-explained. Passwords are guessable, brute-forceable, and get reused. SSH keys are cryptographic — mathematically linked pairs that prove your identity without transmitting a secret over the wire. Once you’re in the habit of using them, you won’t go back.
This guide walks you through generating a key pair using the Ed25519 algorithm, understanding what each piece is and why it matters, and publishing your public key to GitHub and to existing Linux systems.
By the end of this guide, you’ll have:
- A new Ed25519 SSH key pair on your local machine
- A clear mental model of what the public and private keys do
- Your public key added to GitHub
- Your public key deployed to a remote Linux system so you can log in without a password
Prerequisites:
- A terminal — macOS Terminal, iTerm2, or any Linux shell will work. On Windows, use WSL or Git Bash.
- Access to the remote system you want to log into (for the deployment section)
- A GitHub account (for the GitHub section)
What SSH Keys Actually Are
SSH stands for Secure Shell. The keys themselves are a matched pair generated from the same cryptographic operation — you can’t have one without the other, and you can’t derive one from the other after the fact.
The private key is yours alone. It lives on your machine, it never leaves, and you treat it like a password you never type out loud. If someone gets your private key, they are you, as far as every system that trusts it is concerned.
The public key is the part you share. It gets installed on any system you want to access. When you connect, SSH uses the mathematical relationship between the two keys to verify that you hold the private key — without actually sending it. The server challenges you, you respond with a proof derived from your private key, and the server checks it against the public key it already has. No secret crosses the wire.
The analogy that works: the public key is a padlock you give to people. The private key is the only thing that opens it. You can hand out as many padlocks as you want. Only you can open them.
Why Ed25519 and Not RSA
You have options when generating SSH keys — RSA, ECDSA, and Ed25519 are the most common. Ed25519 is the right choice for almost everyone in 2026.
RSA is the old standard. For RSA to be considered secure today, you need a 4096-bit key. That key is large, slow to generate, and produces a long fingerprint. Ed25519 achieves equivalent security with a 256-bit key that’s faster to generate, faster to use, and shorter — which matters when you’re adding it to configuration files and authorized_keys entries. Ed25519 is also more resistant to side-channel attacks than RSA, and the math underlying it (Curve25519, designed by Daniel J. Bernstein) is considered conservative and trustworthy.
Unless you’re connecting to a legacy system that specifically requires RSA, use Ed25519.
Step 1: Generate a Key Pair
Open a terminal and run:
ssh-keygen -t ed25519 -C "you@example.com"The -t ed25519 flag specifies the key type. The -C flag appends a comment to the public key — it doesn’t affect the cryptography, but it makes the key identifiable when you’re looking at an authorized_keys file six months later with a dozen entries in it. Use your email address or a descriptive label like north@macbook-pro.
You’ll be prompted for a location to save the key:
Enter file in which to save the key (/Users/north/.ssh/id_ed25519):
Press Enter to accept the default unless you have a specific reason to name it differently. The default path is ~/.ssh/id_ed25519.
Next, you’ll be prompted for a passphrase:
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Use a passphrase. This is the step most tutorials gloss over, and it’s worth pausing on. If someone gets access to your machine — physically or via malware — and your private key has no passphrase, they have everything. A passphrase encrypts the private key on disk, so a stolen key file is useless without it. Length matters more than complexity: something like correct-horse-battery-staple-2026 is strong and memorable. Store it in your password manager.
The full output will look something like this:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/north/.ssh/id_ed25519):
Enter passphrase for "/Users/north/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/north/.ssh/id_ed25519
Your public key has been saved in /Users/north/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx you@example.com
The key's randomart image is:
+--[ED25519 256]--+
| .o+ |
| . +oE |
| . = +. |
| . + B o. |
| . S B.. |
| . = *o |
| o +.+. |
| . .o. |
| .... |
+----[SHA256]-----+
You now have two files in ~/.ssh/:
id_ed25519— your private key. Guard this. Never paste it anywhere, never email it, never share it.id_ed25519.pub— your public key. This is what you distribute.
To confirm they exist:
ls -la ~/.ssh/Step 2: Add the Key to ssh-agent
If you set a passphrase (you should have), you’d normally need to enter it every time you use the key. ssh-agent solves this by holding your decrypted private key in memory for your session, so you type the passphrase once and it handles authentication silently after that.
Start the agent if it isn’t running:
eval "$(ssh-agent -s)"Add your key to it:
ssh-add ~/.ssh/id_ed25519You’ll be prompted for your passphrase once. On macOS, you can add --apple-use-keychain to persist it across reboots:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519And add the following to ~/.ssh/config so macOS loads it automatically on login:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
On Linux, ssh-agent is typically started by your desktop environment or ~/.profile. The ssh-add command is the same; the keychain flag is macOS-specific.
Step 3: Publish Your Public Key to GitHub
GitHub stores your public SSH keys and — this is the part most guides skip — makes them publicly accessible at a well-known URL: https://github.com/yourusername.keys. Any key you add to your GitHub account is served from that address as plain text.
This turns out to be enormously useful beyond git. When you provision a new Linux system — a VPS, a home server, a Raspberry Pi — many installers and provisioning tools know how to fetch keys from that URL. You give them your GitHub username, they pull your public key, and by the time the system finishes booting you can already SSH into it from your local machine. No password ever set. No manual key copying. The machine trusts you from the start.
Adding Your Key to GitHub
First, copy your public key to the clipboard.
On macOS:
pbcopy < ~/.ssh/id_ed25519.pubOn Linux:
cat ~/.ssh/id_ed25519.pubThen select and copy the output manually — it’s a single long line starting with ssh-ed25519.
In GitHub:
- Click your avatar in the top-right corner
- Go to Settings → SSH and GPG keys
- Click New SSH key
- Give it a descriptive title (e.g.,
MacBook Pro 2025orhome-workstation) - Paste the public key into the Key field
- Click Add SSH key
To verify it’s working:
ssh -T git@github.comYou should see:
Hi yourusername! You've successfully authenticated, but GitHub does not provide shell access.
That’s expected — it confirms the key is recognized. From here, you can clone repositories over SSH (git@github.com:user/repo.git) instead of HTTPS, and push without entering credentials.
Provisioning a New Linux System with Your GitHub Key
The Ubuntu Server installer includes a step that asks if you want to import SSH keys from GitHub or Launchpad. Enter your GitHub username and it fetches your public key from https://github.com/yourusername.keys and writes it into ~/.ssh/authorized_keys during setup. When the machine comes up, you can SSH straight in.
The same thing works on a running Ubuntu or Debian system with ssh-import-id:
ssh-import-id gh:yourusernamessh-import-id fetches your keys from GitHub and appends them to ~/.ssh/authorized_keys automatically, handling permissions correctly. It’s in the default Ubuntu package repositories:
sudo apt install ssh-import-idMany VPS providers — DigitalOcean, Hetzner, Vultr, and others — also offer a “add SSH key” step during droplet/server creation. The mechanics are the same: your public key goes into authorized_keys at provisioning time, root password login is often disabled by default, and you’re in via SSH key from the first boot.
The pattern is: add your key to GitHub once, then reference your username during any new system setup. The public URL does the work.
Step 4: Publish Your Public Key to a Remote Linux System
For SSH access to a server — a VPS, a home server, a Raspberry Pi — you need to add your public key to the ~/.ssh/authorized_keys file on that machine. Any key in that file is trusted to log in as that user.
The Clean Way: ssh-copy-id
If you currently have password access to the remote system, ssh-copy-id handles everything for you:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote-hostReplace user with your username on the remote system and remote-host with the IP address or hostname. You’ll be prompted for the remote system’s password once. After that, it copies your public key into ~/.ssh/authorized_keys on the remote machine and sets the correct file permissions (700 on ~/.ssh/, 600 on authorized_keys). Permissions matter — SSH will refuse to use the authorized_keys file if it’s world-readable.
One useful detail: ssh-copy-id is idempotent. If you run it twice, it won’t add a duplicate entry. Safe to run again if you’re not sure.
To use a non-standard port:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 user@remote-hostThe Manual Way
If password authentication is already disabled on the remote (common on hardened servers), or if you’re provisioning a system and need to add keys directly, do it by hand.
On the remote system, make sure the .ssh directory exists with correct permissions:
mkdir -p ~/.ssh
chmod 700 ~/.sshThen append your public key to the authorized_keys file. On your local machine, get the contents of your public key:
cat ~/.ssh/id_ed25519.pubCopy that output, then on the remote machine:
echo "paste-your-public-key-here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysEach key goes on its own line. You can have as many keys as you need in authorized_keys — one per machine or account you want to grant access from.
Test the Connection
ssh user@remote-hostIf your passphrase is loaded into ssh-agent, this should connect without prompting for any credentials. If it’s not, you’ll be asked for your key’s passphrase — not the remote server’s password.
A Note on Private Key Hygiene
A few practices worth building into your workflow:
One key per machine. Generate a new key pair on each computer you use rather than copying your private key between machines. If a machine is lost or compromised, you revoke that one key on every service. You don’t have to rotate every key you own.
Rotate annually. Generating a new key pair once a year is low-effort insurance. Remove the old key from GitHub and your servers’ authorized_keys files once the new one is deployed.
Never copy the private key. If you’re setting up a new machine, generate a new key pair there. The private key is private — it never moves.
The next person setting up SSH on a new machine shouldn’t have to figure out half of this from error messages. This is the path.