Last Updated: 2026-02-16 by Keming He
Important
This guide is for macOS / Linux users with POSIX-compatible shell (sh, bash, zsh).
For Windows users: See GitHub: Connecting to GitHub with SSH.
Authenticate to Git hosting services and remote servers using SSH keys.
- Use Cases - SSH Authentication
- Passwordless auth: No prompts for git operations or server logins
- More secure: Key-based authentication is stronger than passwords
- One setup, multiple uses: Same key works for Git hosting, servers, and file transfer
ls -la ~/.sshLook for files like id_ed25519 and id_ed25519.pub (or id_rsa/id_rsa.pub). If you have a key pair, you can skip to Add to ssh-agent.
Ed25519 (recommended - smaller, faster, more secure):
ssh-keygen -t ed25519 -C "your-email@example.com"When prompted:
- Press Enter to accept the default file location (
~/.ssh/id_ed25519) - Enter a passphrase (optional but recommended)
Tip
Passphrase adds security - if your private key is compromised, the attacker still needs the passphrase. The ssh-agent caches it so you don't type it repeatedly.
For legacy systems that don't support Ed25519:
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"The ssh-agent caches your key so you don't enter the passphrase repeatedly.
# Start agent (usually auto-started on macOS)
eval "$(ssh-agent -s)"
# Add key
ssh-add ~/.ssh/id_ed25519
# macOS - Use keychain for persistence across reboots
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# macOS - Add to `~/.ssh/config` so keys auto-load:
# Host *
# AddKeysToAgent yes
# UseKeychain yes
# IdentityFile ~/.ssh/id_ed25519# Display public key (copy the output)
cat ~/.ssh/id_ed25519.pub
# macOS: copy directly to clipboard
pbcopy < ~/.ssh/id_ed25519.pubGitHub:
- Go to GitHub Settings > SSH and GPG keys
- Click New SSH key
- Title: descriptive name (e.g., "[Device Name] [YYYY]")
- Key type: Authentication Key
- Paste your public key
- Click Add SSH key
Tip
Use HTTPS URLs but authenticate via SSH - clone commands from GitHub's UI work as-is, no manual URL conversion needed.
git config --global url."git@github.com:".insteadOf "https://github.com/"With this config:
# This HTTPS URL from GitHub's UI...
git clone https://github.com/username/repo.git
# ...automatically uses SSH authentication
# (Git rewrites it to git@github.com:username/repo.git)Note
This rule is applied silently. If you later forget it is set, HTTPS clone URLs will fail with SSH errors like Permission denied (publickey). See Git guide - URL Rewriting Issues for diagnosis and removal instructions.
ssh -T git@github.comExpected output:
Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.The same SSH key can authenticate to Linux servers, cloud VMs, and any SSH-enabled host.
Automatic (recommended):
ssh-copy-id user@remote-hostThis copies your public key to the remote host's ~/.ssh/authorized_keys.
Manual (if ssh-copy-id unavailable):
cat ~/.ssh/id_ed25519.pub | ssh user@remote-host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"ssh user@remote-hostWith a custom port:
ssh -p 2222 user@remote-hostUpload file to remote:
scp local-file.txt user@remote-host:~/Download file from remote:
scp user@remote-host:~/remote-file.txt ./Upload directory (recursive):
scp -r local-dir/ user@remote-host:~/Symptom:
Permission denied (publickey).Causes and fixes:
-
Key not added to target:
- For Git: Check key is in GitHub/GitLab SSH settings
- For servers: Check
~/.ssh/authorized_keyson remote host
-
Key not in ssh-agent:
ssh-add -l # List loaded keys ssh-add ~/.ssh/id_ed25519 # Add if missing
-
Wrong key being used: Create
~/.ssh/configto specify key per host:Host github.com IdentityFile ~/.ssh/id_ed25519 Host work-server HostName 192.168.1.100 User admin IdentityFile ~/.ssh/id_work
Symptom: Key not persisting across terminal sessions.
Fix:
# Restart agent and re-add key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# macOS: use keychain for persistence
ssh-add --apple-use-keychain ~/.ssh/id_ed25519Auto-start on shell login: Add to ~/.bashrc or ~/.zshrc:
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
fiThe ~/.ssh/known_hosts file stores fingerprints of SSH servers you have connected to. SSH checks this file to detect man-in-the-middle attacks.
When to remove a host key:
- The remote server was rebuilt or its SSH key was rotated (you see a
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGEDerror). - A host key was added unintentionally, for example due to Git URL rewriting triggering an unexpected SSH connection.
Remove a host key:
ssh-keygen -R github.comReplace github.com with the hostname you want to remove. The original known_hosts file is backed up automatically as known_hosts.old.
View current known hosts:
cat ~/.ssh/known_hosts