SSH key best practices
SSH keys are the de facto standard for authenticating to infrastructure, but poor management turns every deployment into a potential vulnerability. This note collects proven practices: from key generation to revocation and rotation without service downtime.
Introduction
SSH keys function as long‑lived credentials, and their lifecycle directly impacts supply‑chain security. Unlike passwords, keys are often created once and forgotten, leading to an accumulation of “zombie” keys with privileges that exceed current needs. Proper generation, binding to an agent, and regular rotation minimize the attack surface and enable auditing of changes. The following sections describe concrete commands and configurations used in operations.
Key Generation
Modern OpenSSH defaults recommend the Ed25519 algorithm because of its short key length (256 bits) and high resistance to attacks. RSA still appears in legacy systems but requires increasing the length to at least 4096 bits for acceptable security.
The primary generation command is:
Flag explanations:
-t– cryptographic algorithm type (ed25519,rsa,ecdsa,sk-ed25519@openssh.comfor Security Key).-C– comment, usually an email or service name; it is stored in the key but not used for authentication.-f– path to the key file; if the directory does not exist, it will be created with correct permissions.
For fully automated scenarios (CI/CD, scripts) you can pass an empty passphrase via -N "", but understand the risk: a passwordless key can be used by any process running as the user. It is preferable to use ssh-agent with an unlock session or a key store (Keychain, ssh-agent -s).
Table: Comparison of common key types
| Algorithm | Key length | Primary use | Notes |
|---|---|---|---|
| Ed25519 | 256 bits | Modern infrastructures, deployment scripts | Recommended standard starting with OpenSSH 6.8 |
| RSA | 2048–4096 bits | Legacy systems, some vendor platforms | 4096 bits minimally acceptable; larger is overkill |
| ECDSA | 256–521 bits | Specific requirements, older devices | 521‑bit (P‑521) most secure but less compatible |
When generating keys for different services, it is convenient to split them by files (e.g., id_ed25519_work, id_ed25519_cloud) to simplify revocation and rotation without affecting other contexts.
Using ssh-agent
The SSH agent holds the decrypted key in memory of the current session, avoiding password entry on each connection. Starting the agent and adding a key:
In newer OpenSSH versions (8.2+) the agent can be started in config mode:
The ~/.ssh/config file allows automatically loading keys for specific hosts:
Flags in IdentityFile and AddKeysToAgent guarantee that the key is loaded once on the first connection to a host and remains available for subsequent sessions within the agent’s lifetime. On macOS the flag UseKeychain yes integrates the key with Keychain, locking it when the screen is locked and unlocking when unlocked.
Enable IdentitiesOnly yes in the config if the SSH client begins trying all keys during a connection attempt, which can cause delays or authentication errors on servers with a limited list of allowed keys.
Revocation and Rotation
Keys should not live forever. Rotation policy depends on the infrastructure risk profile, but minimal hygiene includes regular audits and a revocation procedure when personnel change or responsibility shifts.
Revocation procedure:
Remove the public key from the remote server:
or manually edit
~/.ssh/authorized_keysdeleting the line corresponding to the revoked key.Locally delete the key and generate a new one:
Distribute the new public key via IaC or a configuration manager (Ansible, Terraform) to avoid manual edits.
Automated rotation:
For large fleets you can use scripts that check the key creation date (comment -C or metadata inside the key) and automatically revoke keys older than N days. It is important to retain key history for at least 30–90 days before full deletion to avoid breaking services that have not yet updated their configuration.
If a key leak is detected (e.g., in public repositories or logs), act immediately: revoke the key on all hosts, generate a new one, and update the configuration. Do not wait for scheduled rotation—exposure of a key means full loss of control over the associated resources. We need to produce the English version of the article, matching the structure and facts of the Russian draft. The Russian draft sections: Introduction, Генерация ключей (Key generation), Использование ssh-agent (Using ssh-agent), Отзыв и ротация (Revocation and rotation). We need to produce English article, same structure, same commands, tables, admonitions. No front matter, no code fences around whole article. Just markdown body.
We need to translate the Russian content into English, preserving the same details, commands, tables, admonitions. Ensure we keep the same practical tone, short paragraphs, specific commands, tables, code fences with language spec. Use GitHub admonitions as in Russian: > [!TIP], > [!WARNING]. Also maybe > [!NOTE] if needed but Russian didn’t have note. We’ll keep tip and warning.
We need to produce