# SSH Certificates: Login via a Certificate Authority

> SSH certificates replace distributing public keys: users get short-lived certificates from a certificate authority instead of long-term SSH keys.

## 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 `TrustedUserCAKeys` option in `sshd_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 in `authorized_keys` are phased out gradually.
- The `RevokedKeys` list is synced to every server on each revocation.
- In addition to certificates, [two-factor authentication](https://www.zevshost.net/en/kb/dvuhfaktornaya-autentifikatsiya-server/) is enabled for SSH logins.

An SSH CA does not replace baseline [SSH hardening](https://www.zevshost.net/en/kb/ssh-hardening-server/) — disable password login and change the port separately. For a comparison with classic key distribution, see the article on [SSH keys for VPS login](https://www.zevshost.net/en/kb/ssh-klyuchi-vds/).

---

Source: https://www.zevshost.net/en/kb/ssh-sertifikaty-ca/
