SSH Key Management: Best Practices for Developers and Teams
Your SSH keys are the gateway to your infrastructure. Learn how to generate, organize, rotate, and share them securely — from solo developers to enterprise teams.
SSH keys are the foundation of secure remote access. But as your infrastructure grows — more servers, more team members, more environments — managing keys becomes a challenge. This guide covers best practices for every stage of the key lifecycle.
Key Generation
Choose the Right Algorithm
Ed25519 (Recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
- 256-bit security level
- Fastest signing and verification
- Smallest key size
- Resistant to side-channel attacks
RSA (Legacy Compatibility)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
- Use only when Ed25519 isn't supported
- Minimum 4096 bits for modern security
- Slower than Ed25519
ECDSA (NIST Curves)
ssh-keygen -t ecdsa -b 521 -C "your_email@example.com"
- Good performance
- Some organizations have concerns about NIST curves
- Use when Ed25519 isn't an option
Use Descriptive Comments
The -C flag sets a comment that helps identify the key later:
ssh-keygen -t ed25519 -C "macbook-pro-work-2025"
ssh-keygen -t ed25519 -C "personal-laptop-home"
ssh-keygen -t ed25519 -C "ci-deploy-key-production"
When you see this key in authorized_keys or logs, you'll know exactly which device or purpose it's for.
Add a Passphrase
Always protect your private key with a passphrase:
Enter passphrase (empty for no passphrase): [type a strong passphrase]
Enter same passphrase again: [retype]
A passphrase adds an extra layer of security. Even if someone steals your private key file, they can't use it without the passphrase.
Key Organization
Separate Keys by Purpose
Don't use a single key for everything. Create separate keys for:
- Work servers — Corporate infrastructure
- Personal projects — Your own servers and services
- CI/CD pipelines — Automated deployment keys
- GitHub/GitLab — Version control access
- Jump hosts — Bastion server access
This limits the blast radius if a key is compromised.
Use SSH Config
Your ~/.ssh/config file maps hosts to specific keys:
# Work production servers
Host prod-*
User deploy
IdentityFile ~/.ssh/id_work_ed25519
IdentitiesOnly yes
# GitHub
Host github.com
IdentityFile ~/.ssh/id_github_ed25519
IdentitiesOnly yes
# Personal servers
Host home-server
HostName 192.168.1.100
User admin
IdentityFile ~/.ssh/id_personal_ed25519
The IdentitiesOnly yes directive ensures SSH only offers the specified key, preventing unnecessary key exposure.
Directory Structure
Organize keys in subdirectories:
~/.ssh/
├── config
├── known_hosts
├── work/
│ ├── id_ed25519
│ └── id_ed25519.pub
├── personal/
│ ├── id_ed25519
│ └── id_ed25519.pub
└── ci/
├── id_deploy
└── id_deploy.pub
Reference them in your config:
IdentityFile ~/.ssh/work/id_ed25519
Key Rotation
Regular key rotation limits the damage if a key is compromised.
Rotation Schedule
- High-security environments: Every 90 days
- Standard practice: Every 6-12 months
- After incidents: Immediately
Rotation Process
- Generate a new key
ssh-keygen -t ed25519 -C "macbook-pro-2025-rotated" -f ~/.ssh/id_ed25519_new
- Add the new key to servers
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@server
- Verify access with the new key
ssh -i ~/.ssh/id_ed25519_new user@server
- Remove the old key
ssh user@server "sed -i '/old-key-comment/d' ~/.ssh/authorized_keys"
Update SSH config to use the new key
Delete the old key files locally
Team Key Management
For teams, individual authorized_keys entries become unmanageable. Consider these approaches:
SSH Certificates
A Certificate Authority (CA) signs user public keys:
# Sign a user's public key
ssh-keygen -s ca_key \
-I "user@example.com" \
-n ubuntu,root \
-V +52w \
user_key.pub
Servers trust the CA's public key instead of individual user keys. Benefits:
- Short-lived access — Certificates expire (e.g., 52 weeks)
- Centralized authority — One place to issue/revoke access
- Audit trail — Track who accessed what and when
Tools for Large Teams
- HashiCorp Vault — SSH certificate issuance and management
- Teleport — Access plane with short-lived certificates
- Smallstep — Lightweight certificate authority
Storing Keys Securely
File Permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_*
chmod 644 ~/.ssh/*.pub
chmod 600 ~/.ssh/config
Incorrect permissions cause SSH to reject keys for security reasons.
macOS Keychain
Store passphrases in the Keychain:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
No need to type your passphrase every time.
Secure Enclave (FoxTerm)
FoxTerm takes this further by storing keys in the Secure Enclave on supported Apple devices. The private key material never leaves the hardware security module — not even FoxTerm can read it.
Emergency Procedures
Lost or Stolen Device
- Immediately revoke the key from all servers:
ssh user@server "sed -i '/stolen-device-key/d' ~/.ssh/authorized_keys"
Generate a new key on your replacement device
Add the new key to all servers
Investigate how the device was compromised
Compromised Key
If you suspect a key was leaked:
- Revoke immediately from all servers
- Generate a new key with a different algorithm (if possible)
- Audit logs to see if the key was misused
- Rotate related credentials (passwords, API tokens)
The Bottom Line
Good SSH key management is about discipline: generate keys properly, organize them logically, rotate them regularly, and store them securely. Start with the basics and scale up to certificates as your team grows.
Download FoxTerm at foxterm.app for secure key storage with Secure Enclave support.