SSH User Certificates: Short-Lived Access at Scale

The most surprising thing about SSH user certificates is that they offer a way to grant temporary SSH access that’s far more secure and manageable than traditional SSH key management, despite sounding like an over-engineered solution for a simple problem.

Imagine you need to grant engineers temporary access to a fleet of servers for a critical deployment. With traditional SSH keys, you’d be distributing public keys to authorized_keys files on every server, a logistical nightmare prone to errors and security risks. Certificates flip this model: the servers trust a single Certificate Authority (CA) key, and you issue short-lived certificates signed by that CA to your users. When a user presents a certificate, the server verifies its signature against the trusted CA key and checks its validity period.

Let’s see this in action. First, we need a CA.

# Generate a private key for our CA
ssh-keygen -f ca_key -N "" -C "MySSHCA"

# Generate the CA's public key
ssh-keygen -f ca_key.pub

Now, we need to tell our servers to trust this CA. On each server, add the CA’s public key to ~/.ssh/authorized_keys for the root user (or whichever user will be SSHing in).

# Example of ~/.ssh/authorized_keys on a server:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD... MySSHCA

Next, let’s create a user’s private key. This key is not distributed to the servers.

# Generate a user's SSH key pair
ssh-keygen -f user_key -N "" -C "Alice"

Now, we use the CA’s private key (ca_key) to sign the user’s public key (user_key.pub) and create a certificate. We’ll specify a validity period of one day (-V +1d).

# Sign the user's public key with the CA private key
ssh-keygen -s ca_key -I alice_id -n alice,bob -V +1d user_key.pub

This command creates user_key-cert.pub. The -I alice_id is an arbitrary identifier for this certificate, and -n alice,bob specifies the principals (usernames) this certificate is valid for on the target servers.

To SSH in as Alice, she uses her private key (user_key) and the generated certificate (user_key-cert.pub). SSH automatically looks for the certificate alongside the private key.

# Alice's SSH command (from her local machine)
ssh -i user_key root@server.example.com

On the server, the sshd configuration (/etc/ssh/sshd_config) needs to be set up to trust the CA.

# Example sshd_config on a server:
TrustedUserCAKeys /etc/ssh/ca_key.pub

After restarting sshd on the server (systemctl restart sshd), Alice can now SSH in. The server checks user_key-cert.pub against its trusted ca_key.pub. If valid and Alice’s username is in the principals list, access is granted without Alice’s public key ever being on the server.

The real power comes from automation. You can integrate certificate issuance into your CI/CD pipelines or identity management systems. When a user needs access, a script requests a certificate from your CA service, which then signs their public key and returns the certificate. This can be done for minutes, hours, or days, drastically reducing the window of exposure for any compromised credentials.

A common point of confusion is that the ssh-keygen -s command outputs the signed public key (the certificate), not the private key. The user’s private key remains solely on their machine. The certificate is essentially a signed assertion by the CA that "this public key belongs to a user authorized to act as 'alice' or 'bob' until [expiration date]."

The next step in managing access at scale is to implement certificate revocation lists (CRLs) or use a dynamic revocation mechanism if your CA infrastructure supports it.

Want structured learning?

Take the full Ssh course →