Typing a password every time you connect to a server gets old fast, and passwords can be guessed. SSH keys fix both problems. By the end of this guide you will have an ed25519 key protected by a passphrase, a server that accepts it, a short alias so you can type ssh myserver, and the same setup working with your git host.
What you need
- A computer running macOS, Linux, or Windows 10/11 with the built-in OpenSSH client.
- A server or second computer you can already reach with a username and password.
- A terminal (Terminal on macOS, any shell on Linux, PowerShell on Windows).
- About 15 minutes.
The examples use alice as the username, server.example.com as the server, and 203.0.113.10 as its address. Swap in your own.
Step 1: Generate an ed25519 key
Run this on the computer you will connect from. The -C flag adds a comment, usually your email, so you can tell keys apart later.
ssh-keygen -t ed25519 -C "alice@example.com"
Recent OpenSSH versions already default to ed25519, but naming the type makes the command portable. Press Enter to accept the default location. You will see something like this:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/alice/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/alice/.ssh/id_ed25519
Your public key has been saved in /home/alice/.ssh/id_ed25519.pub
You now have two files. id_ed25519 is the private key. Treat it like a password and never share it. id_ed25519.pub is the public key, which is safe to copy anywhere.
Step 2: Add a passphrase and load the key into ssh-agent
When asked for a passphrase, set one. If someone ever copies your private key, the passphrase still stands in their way. If you skipped it, add one later with ssh-keygen -p -f ~/.ssh/id_ed25519.
The ssh-agent remembers the unlocked key so you only type the passphrase once per session.
macOS
Start the agent and add your key to the macOS Keychain:
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Then add these lines to ~/.ssh/config (create the file if it does not exist) so the key loads automatically:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
UseKeychain is an Apple addition, so it only works on macOS.
Linux
Many desktop sessions already run an agent. If yours does not, start one and add the key:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Windows
The ssh-agent service is disabled by default. Open PowerShell as administrator and run:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
Then, in a normal PowerShell window:
ssh-add $env:USERPROFILE\.ssh\id_ed25519
Step 3: Copy your public key to the server
The server keeps a list of trusted public keys in ~/.ssh/authorized_keys. The easiest way to add yours is ssh-copy-id, available on macOS and most Linux systems:
ssh-copy-id -i ~/.ssh/id_ed25519.pub alice@server.example.com
It asks for your server password one last time, creates the file if needed, and skips keys that are already installed.
If you don’t have ssh-copy-id, for example in Windows PowerShell, copy the key file across with scp, then add it to the list on the server:
scp $env:USERPROFILE\.ssh\id_ed25519.pub alice@server.example.com:key.pub
ssh alice@server.example.com "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat ~/key.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && rm ~/key.pub"
These commands are for a Linux or macOS server. Each one asks for your server password. A Windows server stores keys in a different place, and administrator accounts use C:\ProgramData\ssh\administrators_authorized_keys. Follow Microsoft’s guide linked below for that case.
Step 4: Log in and check the host fingerprint
Now connect:
ssh alice@server.example.com
The first time you reach a new server, SSH shows its fingerprint and asks you to confirm:
The authenticity of host 'server.example.com (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:4fXk2...Q9wE.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Don’t type yes on autopilot. If you can, check the fingerprint on the server itself, using a console or an existing session:
ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub
If the two match, type yes. SSH saves the key in ~/.ssh/known_hosts and will warn you if it ever changes. You should now land in a shell without being asked for the server password. You may be asked for your key passphrase once if the agent is not holding it yet.
Step 5: Create a Host alias in ~/.ssh/config
Add an entry to ~/.ssh/config on your own computer:
Host myserver
HostName server.example.com
User alice
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Now this is all you need:
ssh myserver
IdentitiesOnly yes tells SSH to offer only the key you listed.
Step 6: SSH between two of your own machines at home
The same steps work between two computers on your home network. The machine you connect to just needs an SSH server running.
On a Mac, open System Settings, go to General, then Sharing, and turn on Remote Login. Click the info button next to it to see the exact ssh command for that Mac.
On Ubuntu, install the server package:
sudo apt install openssh-server
Find the target machine’s local address in its network settings. Then, from the other computer, copy your key and connect as before, using that address. In this example it is a placeholder:
ssh-copy-id alice@192.168.1.50
ssh alice@192.168.1.50
Step 7 (optional): Turn off password logins
Once key login works, you can stop the server from accepting passwords at all. Bots that guess passwords then have nothing to guess.
Keep your current SSH session open while you do this. If something goes wrong, that open session is how you fix it. Test from a second terminal before closing anything.
On Ubuntu, settings in /etc/ssh/sshd_config.d/ override the main file, and the first value read wins. Files load in name order, so a name starting with 00- is read first:
sudo nano /etc/ssh/sshd_config.d/00-no-passwords.conf
Add these two lines:
PasswordAuthentication no
KbdInteractiveAuthentication no
Check the config for mistakes, then restart the service:
sudo sshd -t
sudo systemctl restart ssh.service
From a new terminal, run ssh myserver to confirm you still get in. Then try ssh -o PubkeyAuthentication=no myserver. It should be refused. Keeping the server’s software up to date matters just as much, for the same reasons covered in our explainer on why prompt patching matters.
Step 8: Connect a git host
Git hosts such as GitHub accept the same key. Print your public key and copy it:
cat ~/.ssh/id_ed25519.pub
Paste it into the SSH keys section of your account settings, following your git host’s guide (GitHub’s is linked below). Then test:
ssh -T git@github.com
A successful test looks like this:
Hi alice! You've successfully authenticated, but GitHub does not provide shell access.
Your git account is a key part of your online identity, so it is worth reviewing the rest of your accounts too. Our guide to finding accounts that use your username can help.
Common errors and fixes
Permission denied (publickey)
The server did not accept any key you offered. Check that the public key is in ~/.ssh/authorized_keys on the server, that you are using the right username, and that the agent holds your key. Run ssh -v myserver to see which keys are tried.
Wrong permissions on ~/.ssh
By default the SSH server ignores your keys if your files are too open. On the server, fix them with:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
WARNING: UNPROTECTED PRIVATE KEY FILE!
Your private key is readable by other users, so SSH refuses to use it. On your own computer, run:
chmod 600 ~/.ssh/id_ed25519
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
The server’s key no longer matches the one in known_hosts. This happens after a server is reinstalled, but it can also signal an attack. Confirm the change is expected, then remove the old entry and reconnect:
ssh-keygen -R server.example.com
The agent has no identities
Running ssh-add -l shows this when the agent is running but holds no keys. Add yours again with ssh-add ~/.ssh/id_ed25519. If you see “Could not open a connection to your authentication agent”, start the agent first, as shown in Step 2.
Wrapping up
You now log in with a key instead of a password, your key is protected by a passphrase, and an alias keeps commands short. Use one key per computer rather than copying a private key around. If a device is lost, delete its public key line from authorized_keys and from your git host.
Once key-based logins feel routine, the same terminal habits carry over to newer developer setups. Our guide to Chrome DevTools MCP shows how to give a coding agent a real browser, and if you are setting up shared accounts for a team, see how to set up ChatGPT Business with roles and SSO.
Sources and official docs
- OpenSSH ssh-keygen manual
- OpenSSH ssh manual
- OpenSSH ssh_config manual
- OpenSSH sshd_config manual
- ssh-copy-id manual page
- GitHub Docs: Generating a new SSH key and adding it to the ssh-agent
- GitHub Docs: Testing your SSH connection
- Microsoft Learn: Key-based authentication in OpenSSH for Windows
- Ubuntu Server docs: OpenSSH server
- Apple Support: Allow a remote computer to access your Mac





Write a response