:INFO Stop typing passwords every time you push to GitHub SSH keys replace your password with a cryptographic key pair. The private key never leaves your machine. The public key goes on the server or in GitHub. When you connect, both keys are checked against each other and you are in, no password required. This tutorial takes you from zero to a working setup with one key for GitHub and one for a remote server, managed by a single config file that handles everything automatically. You will need a terminal, about 30 minutes, and a GitHub account. :IMAGE :STATS [icon:CLOCK] Time needed | About 30 minutes [icon:TARGET] Cost | Free [icon:FIRE] Difficulty | Beginner, no prior SSH experience needed [icon:STAR] What you get | Passwordless login to GitHub and one remote server :INFO Ed25519, not RSA: why this matters There are two key types you will see everywhere: RSA and Ed25519. RSA is the older standard; it is supported by everything but slow to generate and produces long keys. Ed25519 is an elliptic curve algorithm: shorter keys, faster signatures, identical or better security. GitHub, GitLab, Bitbucket and every modern Linux server support it. Unless you are connecting to a legacy system running OpenSSH below version 6.5 (released 2014), use Ed25519. :INFO Step 1. Generate your key pair Run this command on your local machine. The comment after -C is just a label to identify the key later: your email address is conventional, but any string works. :CODE [language:bash] ssh-keygen -t ed25519 -C "your@email.com" Accept the default file path when prompted. This creates two files: the \ private key at ~/.ssh/id_ed25519 and the public key at \ ~/.ssh/id_ed25519.pub. When asked for a passphrase, choose a strong one. \ You will only have to type it once per session if you follow step 5. :NOTE Never share the file id_ed25519. That is your private key. The file you share is id_ed25519.pub, the one with .pub at the end. The private key stays on your machine only. :INFO Step 2. Copy the public key to a remote server If you have a remote server you SSH into with a password, copy the public key there now. The ssh-copy-id command handles the file placement and permissions in one step. :CODE [language:bash] ssh-copy-id user@your-server-ip Type your password one final time. The command appends your public key to \ ~/.ssh/authorized_keys on the server with the correct permissions. \ After this, you can log in without a password. If ssh-copy-id is not available (on some minimal systems), use the manual \ command below. It does exactly the same thing. :CODE [language:bash] cat ~/.ssh/id_ed25519.pub | ssh user@your-server-ip \ "mkdir -p ~/.ssh && chmod 700 ~/.ssh && \ cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" Test it immediately: :CODE [language:bash] ssh user@your-server-ip If the key is accepted you land at the prompt with no password prompt. :INFO Step 3. Add the public key to GitHub GitHub uses your public key to verify pushes and pulls over SSH. Print your public key, then copy the entire output. :CODE [language:bash] cat ~/.ssh/id_ed25519.pub Go to github.com, click your avatar, then Settings, then SSH and GPG \ keys. Click New SSH key, give it a name (like "Work MacBook"), paste the \ key and save. Test the connection from your terminal. :CODE [language:bash] ssh -T git@github.com A successful response looks like: Hi username! You have successfully \ authenticated, but GitHub does not provide shell access. :LINK https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account GitHub official docs: adding an SSH key to your account :INFO Step 4. The ~/.ssh/config file This is the piece that makes everything click. Without a config file, you type the full username, hostname and port every time. With one, you type ssh work or git push and it handles everything. Create or open the config file in your editor. It has no extension. :CODE [language:bash] mkdir -p ~/.ssh && chmod 700 ~/.ssh nano ~/.ssh/config Paste this template, adjusting the values for your setup. Each Host block \ is a named shortcut. :CODE [language:plaintext] # GitHub Host github.com HostName github.com User git IdentityFile ~/.ssh/id_ed25519 AddKeysToAgent yes # Personal VPS or home server Host myserver HostName 203.0.113.5 User ubuntu Port 22 IdentityFile ~/.ssh/id_ed25519 # Work server (if you use a separate key for work) Host work HostName work.example.com User deploy Port 2222 IdentityFile ~/.ssh/id_ed25519_work Set the permissions on the config file: :CODE [language:bash] chmod 600 ~/.ssh/config Now ssh myserver connects to 203.0.113.5 as ubuntu with your key. \ Git operations against github.com use the GitHub block automatically. :INFO Step 5. macOS only: keep your passphrase in Keychain On macOS, the ssh-agent can store your key passphrase in the system Keychain so you only type it once after a reboot, never again mid-session. Add these two lines to the Host * block (or the top of config if you have no wildcard block yet). :CODE [language:plaintext] Host * AddKeysToAgent yes UseKeychain yes Then add your key to the agent for this session: :CODE [language:bash] ssh-add --apple-use-keychain ~/.ssh/id_ed25519 From the next login onward, macOS loads the key automatically. Linux \ users: most desktop environments start ssh-agent automatically. If yours \ does not, add eval "$(ssh-agent -s)" and ssh-add to your shell profile. :NOTE UseKeychain yes is a macOS-only option (ignored on Linux). It is what saves the passphrase to the macOS Keychain. AddKeysToAgent yes works on both platforms and tells the agent to hold the key for the session. :INFO Step 6. Harden the server: disable password login Once key-based login is confirmed working, disable password authentication on the server entirely. This removes the single biggest attack vector for a public-facing server. :CODE [language:bash] sudo nano /etc/ssh/sshd_config Find or add these two lines: :CODE [language:plaintext] PasswordAuthentication no PubkeyAuthentication yes Reload the SSH daemon to apply the change. Do not close your existing \ session until you have verified a new login works from a second terminal. :CODE [language:bash] sudo systemctl reload sshd Open a new terminal and run ssh myserver (or use your Host alias). If \ you land at the prompt, you are done. Password login is now blocked for \ everyone, including attackers. :LINK https://goteleport.com/blog/how-to-set-up-ssh-keys/ GoTeleport: SSH key setup guide covering Ed25519 generation and server auth :NOTE Quick reference: files to know. ~/.ssh/id_ed25519 is your private key, never share it. ~/.ssh/id_ed25519.pub is your public key, safe to share. ~/.ssh/authorized_keys (on the server) is where valid public keys live. ~/.ssh/config is your client-side shortcut file.