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_ed25519

You’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_ed25519

And 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.pub

On Linux:

cat ~/.ssh/id_ed25519.pub

Then select and copy the output manually — it’s a single long line starting with ssh-ed25519.

In GitHub:

  1. Click your avatar in the top-right corner
  2. Go to SettingsSSH and GPG keys
  3. Click New SSH key
  4. Give it a descriptive title (e.g., MacBook Pro 2025 or home-workstation)
  5. Paste the public key into the Key field
  6. Click Add SSH key

To verify it’s working:

ssh -T git@github.com

You 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:yourusername

ssh-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-id

Many 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-host

Replace 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-host

The 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 ~/.ssh

Then append your public key to the authorized_keys file. On your local machine, get the contents of your public key:

cat ~/.ssh/id_ed25519.pub

Copy that output, then on the remote machine:

echo "paste-your-public-key-here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Each 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-host

If 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.


Footnotes