SSH Keys Explained: Set Them Up Once, Properly
SSH keys are how you log into servers and push to GitHub without passwords. What the two halves of a key pair do, how to create a modern one, using ssh-agent and a config file so you stop retyping things, and the habits that matter: passphrases, one key per device, never sharing a private key.
Sooner or later, you need SSH: to push code to GitHub, to log into a server, or to reach a remote development environment. The setup takes five minutes — and it's easy to do in a way that's either insecure or annoying. Here's how to do it once, properly.
What an SSH key is
An SSH key is a pair of files:
- The private key stays on your computer. It proves you are you. Never share it, email it, paste it anywhere, or copy it to a server.
- The public key can be shared freely. You give it to GitHub or put it on a server, and it lets that service recognise your private key.
When you connect, the server sends a challenge that only the holder of the private key can answer. Your private key never leaves your machine. That's why SSH keys are both more secure and more convenient than passwords: there's nothing to phish, nothing sent over the network to steal, and nothing to type every time.
Step 1: check whether you already have one
ls ~/.ssh
Files like id_ed25519 and id_ed25519.pub mean you already have a key pair (the .pub one is the public half). You can use it, or create a new one.
Step 2: create a key
ssh-keygen -t ed25519 -C "[email protected]"
-t ed25519— a modern key type: short, fast, and secure. Use it unless some old system can't accept it, in which case-t rsa -b 4096is the fallback.-C— a comment, just a label. Your email, or something likelaptop-2026.
It asks where to save it (the default is fine) and for a passphrase. Set one. The passphrase encrypts the private key file, so if your laptop is stolen or the file is copied, the key is useless without it. The next step means you'll rarely have to type it.
This works on macOS, Linux, and Windows — Windows 10 and 11 include OpenSSH, so the same command works in PowerShell.
Step 3: use ssh-agent so you type the passphrase once
The SSH agent holds your unlocked key in memory, so you enter the passphrase once per login session rather than every connection.
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
On macOS, add --apple-use-keychain to ssh-add to store the passphrase in the Keychain, so it survives restarts. On Windows, the "OpenSSH Authentication Agent" service does the same job once it's enabled. Many password managers can also act as an SSH agent, which keeps the private key in your vault instead of a file.
Step 4: add the public key where you need it
GitHub (or GitLab, Bitbucket): copy the public key —
cat ~/.ssh/id_ed25519.pub
— and paste it into your account's SSH keys settings. Then test:
ssh -T [email protected]
A server: add the public key to ~/.ssh/authorized_keys for your user on the server. The easy way:
ssh-copy-id user@your-server
Then log in with ssh user@your-server — no password asked.
Double-check you copied the file ending in .pub. Pasting a private key into a website is the most common serious mistake with SSH keys. If you ever do it, delete that key pair and make a new one.
Step 5: a config file, so you stop typing addresses
~/.ssh/config lets you give servers short names and settings:
Host devbox
HostName 203.0.113.42
User dev
IdentityFile ~/.ssh/id_ed25519
Host *
AddKeysToAgent yes
ServerAliveInterval 60
Now ssh devbox does the right thing. ServerAliveInterval stops idle connections being dropped by routers — especially useful for long-running terminal sessions.
Security habits that matter
One key per device. Your laptop, your desktop, and your phone's SSH app should each have their own key pair. If one device is lost, you remove that device's public key from GitHub and your servers, and everything else keeps working. Copying one private key to every device means losing any device compromises all of them.
Always use a passphrase on keys stored as files.
Remove keys you don't use. Review the SSH keys listed in your GitHub account and in servers' authorized_keys files occasionally. Old keys from old laptops are unnecessary risk.
Don't copy private keys to servers. A common shortcut is to put your GitHub key on a server so it can pull code. Better: use agent forwarding carefully (ssh -A, only to servers you trust, since root on that server can use your agent while you're connected), or give the server its own key with limited access — GitHub deploy keys are scoped to a single repository and can be read-only.
Harden servers. On servers you run, disable password login entirely once key login works, and never allow root login with a password. (How to Run Claude Code on a Remote Server walks through basic hardening.)
Verify host fingerprints. The first time you connect to a server, SSH shows its fingerprint and asks you to confirm. If you later see a warning that the host key has changed, stop and find out why before continuing — it can mean someone is intercepting the connection. (It more often means the server was rebuilt, but check.)
Keys and AI agents
If an AI agent runs on your laptop, it can read ~/.ssh — every private key you have, including the ones for production servers. A passphrase helps if the key file is copied, but not if the agent can use your unlocked agent.
That's one of the strongest arguments for running agents somewhere other than your personal machine: an environment with only the credentials that project needs, like a deploy key for one repository. How to Run AI-Generated Code Safely covers the rest.
Quick reference
ssh-keygen -t ed25519 -C "laptop-2026" # create a key
ssh-add ~/.ssh/id_ed25519 # load it into the agent
cat ~/.ssh/id_ed25519.pub # show the PUBLIC key to copy
ssh-copy-id user@server # install it on a server
ssh -T [email protected] # test GitHub
EasySpawn workspaces are reachable over SSH as well as the web and your phone, and connect to GitHub via OAuth — so the workspace has access to your repositories without your personal private keys ever being copied into it. See how it works or join the waitlist.
Related: A tmux Cheat Sheet for Long-Running Sessions · Can You Really Code on an iPad or Chromebook? · What Is an IP Address and a Port?
Keep reading
How to Update Your App's Dependencies Safely
The packages your app is built on get security fixes and new versions constantly. Ignore them and you accumulate risk; update carelessly and the app breaks. What version numbers mean, a safe routine for updating, how to handle security warnings, and how to let an AI do the tedious part.
What Is .gitignore? Keeping Secrets and Junk Out of Git
A .gitignore file tells Git which files never to save — your .env secrets, node_modules, build output, and OS clutter. How it works, the pattern syntax, a starter file for JavaScript projects, and what to do if you already committed something you shouldn't have.