Why manual SSH key management falls short
On a server with a dozen administrators, the ~/.ssh/authorized_keys file on every machine becomes its own source of truth. An employee leaves — someone has to manually remove their key from every server. A new server appears — someone has to distribute every current key to it. As infrastructure grows this turns into manual synchronization of dozens of files, and some of them inevitably drift from reality.
SSH certificates solve the problem differently: instead of distributing public keys, the server trusts a single certificate authority (CA). A user gets not a permanent key but a short-lived certificate signed by the CA, and revoking access comes down to expiration or a single entry in a revocation list.
How an SSH CA works
The model is built around a key pair belonging to the certificate authority itself:
- The CA holds a private key and signs users' or hosts' public keys, issuing a certificate with a limited validity period.
- Servers configure trust in the CA's public key once, through the
TrustedUserCAKeysoption insshd_config. - A user presents a certificate instead of a bare key when connecting — sshd checks the CA's signature and the validity period.
The same scheme works the other way around too — a Host CA signs server keys, and clients stop getting the untrusted-host warning on the first connection to a new server.
Setting up the certificate authority
Deploy the CA on a separate hardened machine, not on a working server:
ssh-keygen -t ed25519 -f /etc/ssh-ca/user_ca -C "zevshost-user-ca"
ssh-keygen -t ed25519 -f /etc/ssh-ca/host_ca -C "zevshost-host-ca"
Store the private keys user_ca and host_ca offline or in a separate secrets store — compromising the CA gives access to every server that trusts it.
Issuing a certificate for a user
The user generates an ordinary key pair and sends the public key to be signed:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
ssh-keygen -s /etc/ssh-ca/user_ca -I "ivan@zevshost" \
-n ivan -V +12h -z 1001 ~/.ssh/id_ed25519.pub
The -V +12h flag limits the certificate's validity to 12 hours — after that a new certificate must be issued. The -n flag sets the list of principals (logins) the certificate is valid for, and -z sets a serial number for targeted revocation.
Configuring the server for certificates
On every server that should trust the CA, add to /etc/ssh/sshd_config:
TrustedUserCAKeys /etc/ssh/user_ca.pub
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
RevokedKeys /etc/ssh/revoked_keys
The file user_ca.pub is the CA's public key copied from the CA server, not the private one. Next, restart sshd:
sudo systemctl restart sshd
Revoking a specific certificate means adding its serial number or the user's key to the revoked_keys file with ssh-keygen -k, without reinstalling access on the remaining servers.
SSH CA rollout checklist
- The CA runs on a separate machine, and its private key never leaves the hardened storage.
- User certificates are issued with a 12-hour TTL and a mandatory list of principals.
- Servers are configured to trust the CA through
TrustedUserCAKeys, and plain keys inauthorized_keysare phased out gradually. - The
RevokedKeyslist is synced to every server on each revocation. - In addition to certificates, two-factor authentication is enabled for SSH logins.
An SSH CA does not replace baseline SSH hardening — disable password login and change the port separately. For a comparison with classic key distribution, see the article on SSH keys for VPS login.