SSH Keys
SSH keys provide a secure, passwordless way to authenticate to remote servers and services. This page covers generating keys, deploying them, managing multiple identities, and key rotation.
Key Types
| Type | Recommendation | Notes |
|---|---|---|
| ED25519 | Preferred | Fast, small key size, strong security |
| ECDSA | Acceptable | Use -b 521 for the strongest curve |
| RSA | Legacy | Use -b 4096 if ED25519 is not supported |
| DSA | Avoid | Deprecated; not supported in OpenSSH 7.0+ |
Generating a Key Pair
# Generate an ED25519 key (recommended)
ssh-keygen -t ed25519 -C "your-comment"
# Generate an RSA key (4096-bit minimum if ED25519 is unavailable)
ssh-keygen -t rsa -b 4096 -C "your-comment"The -C flag adds a comment to the public key to help identify it — typically an email address, hostname, or purpose (e.g. work-laptop, github).
When prompted:
- File location — Press Enter to accept the default (
~/.ssh/id_ed25519) or specify a custom path for multiple keys - Passphrase — Strongly recommended; encrypts the private key at rest
This produces two files:
~/.ssh/id_ed25519— private key (never share this)~/.ssh/id_ed25519.pub— public key (safe to share)
Deploying a Key to a Server
Using ssh-copy-id (recommended)
# Copy your public key to the remote server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# Specify a non-standard port
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 9437 user@serverManually
# On the server, append the public key to authorized_keys
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "<paste-public-key-here>" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysPermissions must be exact — SSH will silently refuse keys if they are too permissive.
Adding Keys to GitHub / GitLab
# Print the public key to copy to your clipboard
cat ~/.ssh/id_ed25519.pub- Copy the output
- GitHub: Settings → SSH and GPG keys → New SSH key
- GitLab: Preferences → SSH Keys → Add new key
Test the connection after adding:
ssh -T git@github.com
ssh -T git@gitlab.comManaging Multiple Keys with ~/.ssh/config
When you have different keys for different hosts (e.g. personal vs. work GitHub, multiple servers), use ~/.ssh/config to map hosts to their keys automatically.
# Create or edit the SSH config file
nano ~/.ssh/config# Personal GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
# Work GitHub
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
# Production server
Host prod
HostName 10.0.1.50
User deploy
Port 9437
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes# Set correct permissions on the config file
chmod 600 ~/.ssh/configWith this config, you can use the alias instead of the full hostname:
# Clone using the work GitHub alias
git clone git@github-work:org/repo.git
# SSH to the production server using its alias
ssh prodIdentitiesOnly yes tells SSH to use only the key specified in the config and not to try others from the agent — this prevents unexpected key usage.
SSH Agent
The SSH agent holds decrypted private keys in memory so you only need to enter the passphrase once per session.
# Start the agent (usually already running in a desktop session)
eval "$(ssh-agent -s)"
# Add the default key
ssh-add
# Add a specific key
ssh-add ~/.ssh/id_ed25519_work
# List keys currently loaded in the agent
ssh-add -l
# Remove a specific key from the agent
ssh-add -d ~/.ssh/id_ed25519_work
# Remove all keys from the agent
ssh-add -DPersist Agent Keys Across Sessions (macOS / systemd)
On macOS, add this to ~/.ssh/config to use the keychain:
Host *
AddKeysToAgent yes
UseKeychain yesOn Linux with systemd, create a user service or use ~/.bashrc / ~/.zshrc:
# Add to ~/.bashrc or ~/.zshrc
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)" > /dev/null
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fiViewing and Verifying Keys
# Show the fingerprint of a public key
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# Show the fingerprint in a visual (randomart) format
ssh-keygen -lvf ~/.ssh/id_ed25519.pub
# Show all public keys on a remote server's authorized_keys
cat ~/.ssh/authorized_keys
# View the comment and type of a public key
cat ~/.ssh/id_ed25519.pubKey Rotation
Rotate keys when:
- A key or device is compromised
- An employee with key access leaves
- As part of a regular security review
# 1. Generate a new key pair
ssh-keygen -t ed25519 -C "rotated-$(date +%Y-%m)" -f ~/.ssh/id_ed25519_new
# 2. Deploy the new public key to all target servers
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server
# 3. Verify login works with the new key before removing the old one
ssh -i ~/.ssh/id_ed25519_new user@server
# 4. Remove the old public key from each server's authorized_keys
# Edit the file and delete the line containing the old key fingerprint
nano ~/.ssh/authorized_keys
# 5. Delete the old private key locally once confirmed
rm ~/.ssh/id_ed25519_old
rm ~/.ssh/id_ed25519_old.pubPermissions Reference
SSH will refuse to use keys or configs with incorrect permissions.
| Path | Required Permission |
|---|---|
~/.ssh/ | 700 |
~/.ssh/authorized_keys | 600 |
~/.ssh/config | 600 |
~/.ssh/id_ed25519 (private key) | 600 |
~/.ssh/id_ed25519.pub (public key) | 644 |
# Fix permissions in one pass
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys ~/.ssh/config ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pubBest Practices
- Always protect private keys with a passphrase
- Use ED25519 keys; avoid RSA keys shorter than 4096 bits and never use DSA
- Use a separate key per device — if a device is compromised, revoke only that key
- Use descriptive comments (
-C) to track which key belongs to which device or purpose - Regularly audit
authorized_keyson servers and remove stale entries - Never store private keys in version control, cloud storage, or email
- Use
IdentitiesOnly yesin~/.ssh/configto prevent unintended key negotiation