SSH certificates and CAs

SSH · Expert · 15 min

At scale, certificates replace sprawling authorized_keys and known_hosts files with short-lived, centrally issued credentials.

Managing authorized_keys on hundreds of servers, and known_hosts on every laptop, does not scale. OpenSSH supports its own certificates (not X.509): a CA key signs a public key together with metadata.

User certificates. The CA signs a user's public key with an identity, a list of principals (allowed login names) and a validity period:

ssh-keygen -s user_ca -I alice@corp -n alice,deploy -V +8h id_ed25519.pub produces id_ed25519-cert.pub, which ssh picks up automatically next to the key. Servers need just one line, TrustedUserCAKeys /etc/ssh/user_ca.pub, and accept any valid certificate whose principals include the target account. Short validity (hours) means you rarely need revocation; RevokedKeys handles the rest.

Host certificates. Sign each server's host key with -h: ssh-keygen -s host_ca -h -I web1 -n web1.example.com ssh_host_ed25519_key.pub, configure HostCertificate in sshd, and clients trust all of them with one known_hosts line: @cert-authority *.example.com ssh-ed25519 AAAA.... No more first-connect prompts or changed-key warnings after rebuilds.

ssh-keygen -L -f id_ed25519-cert.pub shows a certificate's contents. Tools like Vault, step-ca and Teleport automate issuing certificates after an SSO login.

Example

# CA side: create CAs once, keep them very safe
ssh-keygen -t ed25519 -f user_ca -C "user CA"
ssh-keygen -t ed25519 -f host_ca -C "host CA"

# issue an 8-hour certificate for alice, valid for logins as alice or deploy
ssh-keygen -s user_ca -I alice@corp -n alice,deploy -V +8h ~/.ssh/id_ed25519.pub
ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub     # inspect principals and validity

# server: /etc/ssh/sshd_config
#   TrustedUserCAKeys /etc/ssh/user_ca.pub
#   HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
# sign the host key:
ssh-keygen -s host_ca -h -I web1 -n web1.example.com /etc/ssh/ssh_host_ed25519_key.pub
# client: ~/.ssh/known_hosts
#   @cert-authority *.example.com ssh-ed25519 AAAAC3Nz... host CA

Remember

  • A CA signs user keys (principals + validity) and host keys (-h)
  • Servers: TrustedUserCAKeys; clients: @cert-authority in known_hosts
  • Short-lived certificates make revocation mostly unnecessary

Watch out for

  • Forgetting -n principals: a certificate with no principals is not accepted for any login by default on servers using TrustedUserCAKeys.

Check yourself

  1. What does a server need in order to accept user certificates from your CA?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: man.openbsd.org/ssh-keygen#CERTIFICATES

Builds on

Unlocks

Nothing builds on this yet.