SSH and Keys: Complete Security Guide
Practical guide to SSH and key authentication. Generation, configuration and best practices for secure connections.
Understanding SSH Authentication
SSH (Secure Shell) keys provide a more secure and convenient way to authenticate to remote servers and services like GitHub, GitLab, and cloud providers. Instead of typing passwords, SSH keys use cryptographic key pairs to prove your identity.
This guide covers everything you need to know about generating, managing, and securing SSH keys for modern development workflows.
How SSH Key Authentication Works
SSH key authentication uses asymmetric cryptography with a pair of mathematically related keys:
- Private key: Secret file stored on your computer—never share this
- Public key: Shareable file placed on servers you want to access
When you connect, the server encrypts a challenge with your public key. Only your private key can decrypt it, proving your identity without transmitting passwords.
Benefits Over Passwords
- Security: Keys are much harder to brute-force than passwords
- Convenience: No typing passwords for every connection
- Automation: Enable secure scripts and CI/CD pipelines
- Auditability: Track which key accessed what
Generating SSH Keys
Recommended Algorithm: Ed25519
Ed25519 is the modern standard for SSH keys—it's fast, secure, and produces compact keys:
# Generate Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Output:
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (~/.ssh/id_ed25519):
RSA Alternative
If you need RSA for compatibility with older systems, use at least 4096 bits:
# Generate RSA key (4096 bits)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
Key Generation Options
| Algorithm | Key Size | Security Level | Recommendation |
|---|---|---|---|
| Ed25519 | 256 bits | ~128-bit | Best choice |
| RSA | 4096 bits | ~140-bit | Legacy support |
| ECDSA | 521 bits | ~256-bit | Avoid (NSA concerns) |
| DSA | 1024 bits | ~80-bit | Deprecated |
Setting a Passphrase
Always set a strong passphrase to protect your private key:
Enter passphrase (empty for no passphrase): [type your passphrase]
Enter same passphrase again: [confirm passphrase]
A good passphrase is at least 16 characters, memorable to you, and includes mixed characters. Consider using a password manager to generate and store it.
SSH Key File Locations
Default Paths
# Linux/macOS
~/.ssh/id_ed25519 # Private key
~/.ssh/id_ed25519.pub # Public key
# Windows
C:\Users\YourName\.ssh\id_ed25519
C:\Users\YourName\.ssh\id_ed25519.pub
Correct Permissions
SSH enforces strict file permissions for security:
# Linux/macOS
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/config
SSH will refuse to use keys with incorrect permissions.
Adding Your Key to SSH Agent
The SSH agent remembers your passphrase so you don't retype it for every connection:
Linux/macOS
# Start the SSH agent
eval "$(ssh-agent -s)"
# Add your key
ssh-add ~/.ssh/id_ed25519
# Verify loaded keys
ssh-add -l
macOS Keychain Integration
# Add to macOS Keychain (persists after reboot)
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# ~/.ssh/config for automatic loading
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
Windows
# Start ssh-agent service (Administrator PowerShell)
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
# Add key
ssh-add $env:USERPROFILE\.ssh\id_ed25519
Configuring SSH for Multiple Keys
SSH Config File
The ~/.ssh/config file manages multiple keys and hosts:
# Personal GitHub account
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
# Work GitHub account
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
# Production server
Host prod
HostName production.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519_deploy
Port 22
ForwardAgent no
# Jump host (bastion)
Host bastion
HostName bastion.example.com
User admin
IdentityFile ~/.ssh/id_ed25519_admin
# Internal servers via bastion
Host internal-*
ProxyJump bastion
User developer
Usage with Config
# These now use the correct key automatically
git clone git@github.com:user/repo.git
git clone git@github-work:company/repo.git
ssh prod
ssh bastion
Adding Keys to Services
GitHub
# Copy public key to clipboard
# macOS
pbcopy < ~/.ssh/id_ed25519.pub
# Linux
xclip -selection clipboard < ~/.ssh/id_ed25519.pub
# Windows
clip < ~/.ssh/id_ed25519.pub
Then: GitHub → Settings → SSH and GPG keys → New SSH key → Paste
Remote Servers
# Copy key to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# Or manually
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
Verifying Connection
# Test GitHub connection
ssh -T git@github.com
# Hi username! You've successfully authenticated...
# Test server connection
ssh user@server
SSH Key Security Best Practices
Private Key Protection
- Never share your private key—it should never leave your machine
- Always use a passphrase—protects against theft
- Store in encrypted locations—use encrypted home directories
- Backup securely—encrypted backups only
Key Rotation
Regularly rotate SSH keys to limit exposure:
- Generate new keys annually or after suspected compromise
- Deploy new public keys before removing old ones
- Remove old keys from authorized_keys and services
- Keep records of which keys access what
Audit Access
# List authorized keys on a server
cat ~/.ssh/authorized_keys
# Check who has accessed
grep "Accepted publickey" /var/log/auth.log
Disable Password Authentication
Once SSH keys work, disable password login:
# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
# Restart SSH
sudo systemctl restart sshd
Advanced SSH Features
SSH Agent Forwarding
Access services through jump hosts without copying keys:
# ~/.ssh/config
Host bastion
ForwardAgent yes
# Or command line
ssh -A user@bastion
Warning: Only use agent forwarding with trusted hosts—malicious admins can use your forwarded agent.
SSH Certificates
For larger organizations, SSH certificates scale better than individual keys:
# Sign a user key with CA
ssh-keygen -s ca_key -I user@example -n user -V +52w user_key.pub
# Configure server to trust CA
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/ca.pub
FIDO2/Hardware Keys
Use hardware security keys (YubiKey, etc.) for maximum security:
# Generate key requiring hardware touch
ssh-keygen -t ed25519-sk -C "your_email@example.com"
# Each authentication requires physical touch
Troubleshooting SSH Keys
Common Issues
Permission denied (publickey):
- Verify public key is in authorized_keys
- Check file permissions (700 for .ssh, 600 for keys)
- Confirm SSH agent has the key loaded
- Check SSH config is using the right key
Agent has no identities:
# Add your key to the agent
ssh-add ~/.ssh/id_ed25519
Too many authentication failures:
# Specify exact key
ssh -i ~/.ssh/specific_key user@server
# Or use IdentitiesOnly in config
Host server
IdentitiesOnly yes
IdentityFile ~/.ssh/specific_key
Debugging Connections
# Verbose output (increase v's for more detail)
ssh -v user@server
ssh -vv user@server
ssh -vvv user@server
SSH Keys in CI/CD
GitHub Actions
# Store private key as secret
# Settings → Secrets → New repository secret
# workflow.yml
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan github.com >> ~/.ssh/known_hosts
Deploy Keys
For repository access, use deploy keys (one key per repo):
- Generate a dedicated key pair
- Add public key to repo's deploy keys
- Keep private key in CI/CD secrets
Tools for Key Management
- 1Password/Bitwarden: Store passphrases securely
- GPG: Encrypt backup copies of keys
- Vault: Enterprise key management
- sops: Encrypted secret management
When working with encoded data in SSH configurations or debugging, use tools like our Base64 Encoder/Decoder for handling encoded strings.
For verifying file integrity after key generation, our Hash Generator can create checksums of your key files.
Quick Reference
# Generate Ed25519 key
ssh-keygen -t ed25519 -C "email@example.com"
# Add key to agent
ssh-add ~/.ssh/id_ed25519
# Copy public key
cat ~/.ssh/id_ed25519.pub | pbcopy
# Test connection
ssh -T git@github.com
# Copy key to server
ssh-copy-id user@server
# Debug connection
ssh -v user@server
Conclusion
SSH keys are fundamental to secure development workflows. By following the practices in this guide—using Ed25519 keys, strong passphrases, proper permissions, and regular rotation—you'll have a secure and efficient authentication system.
Key takeaways:
- Use Ed25519 keys for new setups
- Always set a strong passphrase
- Configure SSH agent for convenience
- Use SSH config for multiple keys/hosts
- Disable password authentication on servers
- Rotate keys regularly
For more security tools and resources, explore our free developer tools. For comprehensive SSH documentation, see the OpenSSH manual and GitHub's SSH documentation.