smallstep_full_white

SSH vs. X.509 Certificates

linda_ikechukwu.jpg

Linda Ikechukwu

Follow Smallstep
Struggling with gathering, shipping, and rotating SSH public keys for all your users and hosts? Smallstep delivers end-to-end SSH workflow that marries modern identity providers with short-lived SSH certificates and flexible access control. Check it out .

If I walked into a room of 50 engineers and mentioned “digital certificates,” I’d bet at least 70% would immediately think of TLS/SSL certificates—the kind that powers HTTPS. And fair enough. X.509 certificates are everywhere, securing web traffic, authenticating APIs, and encrypting data in transit.

But X.509 isn’t the only game in town.

There’s another kind of digital certificate—one that solves major problems in SSH authentication yet remains criminally underused: OpenSSH (or simply SSH) certificates.

SSH certificates authenticate terminal-to-server access in Unix environments. They eliminate the mess of managing static SSH keys, reduce security risks, and make large-scale deployments far more manageable. Yet, despite being the most secure way to grant SSH access, most engineers don’t even know they exist.

Why?

Probably because SSH certificates weren’t part of the original RFC 4251 SSH spec. OpenSSH—the most widely used SSH implementation—introduced them later as an extension to fix issues of key sprawl, trust-on-first-use vulnerabilities, and tedious key distribution.

We’ve often come across assumptions that SSH certificates are the same as or can be replaced with X.509 certificates. However, that’s not the case.

In this article, we’ll cover:

  1. What SSH certificates are, and how they work

  2. Why they’re a better alternative to SSH key authentication.

  3. How they compare to X.509 certificates, and can they be replaced by x.509 certificates?

If your SSH authentication strategy still relies on manually distributing public keys or—worse—passwords, you might want to rethink your approach. SSH certificates are simpler, more secure, and built for scale—and by the end of this article, you’ll see why.

This article assumes some knowledge of X.509 certs work; if would like to know more about the basics of X.509 and PKI, read  Everything you should know about certificates and PKI but are too afraid to ask

What Are SSH Certificates?

At a high level, an SSH certificate is just a public key with extra metadata—such as an expiration time, a list of allowed principals (users or hosts), and optional constraints like forced commands or restricted access modes.

There are two types of SSH certificates:

  • User certificates – Authenticate users accessing SSH servers
  • Host certificates – Authenticate SSH servers to clients

Unlike X.509 certificates, which require a full-fledged PKI with certificate chains, revocation lists, and complex parsing rules, OpenSSH certificates are designed to be lightweight and practical. A single CA public key can sign multiple certificates, making key distribution and rotation far easier than traditional SSH public key authentication.

It does, however, require more up-front work than a typical SSH public/private key setup, which most people are wary of. But once implemented, the benefits outweigh the trouble—especially when managing a large number of users, hosts, and keys.

Let’s take a look at how SSH authentication works without certificates—and why it often leads to security headaches.

SSH Authentication Without Certificates

In the absence of SSH certificates, teams are stuck with either passwords or public keys for SSH authentication—both of which introduce security and operational challenges that become unmanageable at scale.

Password-Based Authentication: A Security Nightmare

Passwords are the weakest form of authentication. Users tend to reuse weak passwords, making them easy targets for brute-force attacks and credential stuffing. Even with multi-factor authentication (MFA), passwords are still phishable, which is why best practices strongly recommend disabling password-based SSH logins altogether.

Public Key Authentication: A Key Management Headache

Public key authentication provides a more secure alternative to passwords, but it introduces its own set of problems—especially when managing dozens, hundreds, or thousands of users and servers.

When a client connects to a server using public key authentication, two things happen:

Server Verification:

First, the client attempts to verify the server by checking if its public key is in the known_hosts file. If the key isn’t recognized, the user sees a warning:

The authenticity of host 'xxx' can't be established.
    
RSA key fingerprint is SHA256:kfcwi9X8T4nMRw1OM0xDXETGcqjU26/zbM+KqNB6CKw.
    
Are you sure you want to continue connecting (yes/no)?

At this point, the user should verify the fingerprint with the server administrator before proceeding. But that’s not always the reality. Most users just type yes and move on. This is called Trust on First Use (TOFU)—a dangerous anti-pattern where users blindly trust an unverified server, opening the door to man-in-the-middle attacks.

Client Verification:

Next, the server attempts to verify the client by checking if the user’s public key exists in its authorized_keys file. If it does, access is granted. While this sounds straightforward, it introduces three major problems:

Problem 1: TOFU Encourages Poor Security Habits

Users rarely verify SSH fingerprints, meaning an attacker who intercepts the connection just once can permanently trick users into trusting a rogue server.

Problem 2: Key Sprawl and Management Overhead

A 2019 analysis of 15,000 production servers found that out of three million SSH keys, 90% were no longer in use—leaving them potentially exploitable for unauthorized access.

Teams relying on SSH key authentication must manually distribute and maintain authorized_keys files across multiple hosts. As organizations grow, so do the headaches:

  • New employees need to send their public keys to an admin for manual deployment.
  • Departing employees must have their keys manually removed—and if an admin forgets? The key remains valid indefinitely.
  • Some companies use automation tools to sync keys across servers, but if that system is compromised, an attacker can push malicious keys everywhere at once.

Problem 3: No Expiration = Persistent Risk

SSH public keys never expire. If a former employee’s key is not manually removed from all servers, they can retain access indefinitely.

Most modern authentication methods, like OAuth tokens or session-based logins, expire after a set period—SSH keys do not. Some organizations use centralized key management solutions that automatically propagate key removals, but this introduces a single point of failure:

  • If the key management system is hacked, attackers can distribute their own malicious keys to all servers.
  • If the system goes down, legitimate users can lose access to everything.

SSH Authentication with Certificates

SSH certificate-based authentication works similarly to X.509 certificates but with a much simpler implementation. Instead of managing an ever-growing list of static public keys across multiple servers, SSH certificates introduce a trusted Certificate Authority (CA) that signs time-limited credentials for users and hosts. This eliminates the pitfalls of TOFU, key sprawl, and long-lived credentials.

You first set up an SSH CA server—a trusted entity that issues signed certificates for clients (users) and hosts (servers). This CA holds two separate CA key pairs:

  • A User CA for signing and authenticating certificates for client machines.
  • A Host CA for signing and authenticating certificates for servers.

It’s best practice to keep these separate. If one private key is compromised, only one side (users or hosts) needs to be reissued, minimizing disruption.

After generating these CA key pairs, all host machines are configured to trust certificates signed by the User CA private key, and all clients are configured to trust certificates signed by the Host CA private key. From there, the process for issuing certificates is straightforward:

  1. Generating Host Certificates – Each server generates an SSH key pair. The CA signs the public key, creating a host certificate that clients can trust.
  2. Generating User Certificates – Each user also generates an SSH key pair, and the CA signs their public key into a user certificate. Ideally, this process should be fully automated, so users can get signed certificates dynamically when they authenticate with the company’s identity provider (IdP). This is what makes the Smallstep SSH product different.
  3. Mutual Authentication – When a user attempts to SSH into a server, the server presents a valid host certificate, proving its identity to the client, the user presents a valid user certificate, proving their identity to the server, and SSH access is granted only if both certificates are valid and properly signed. This mutual authentication eliminates TOFU, ensuring that clients and servers only trust identities that have been explicitly verified by the organization’s CA.

SSH Certificate based authentication_2022_Nov_15_Op1 (1).png

Granted, this is a bit of an oversimplification of the actual process. If you are looking for a practical walk-through of the process described above, check out our docs on Working with SSH Certificates.

Apart from eliminating mundane key management tasks and TOFU, SSH certificate-based authentication also offers some features which allow for fine-grained access:

  • Certificates expire. Users can be issued short-lived certificates to eliminate the risk of abandoned compromised key bindings. For example, if a developer leaves without having their access revoked, their certificate will expire after a certain period of time, and they will also lose access automatically.
  • Certificates are restricted to certain users (principals). This creates an opportunity to enable role-based access control.
  • Certificates can contain SSH restrictions, e.g., forbidding PTY allocation or port forwarding.

If you want to read more in-depth on why SSH certificate-based authentication is the most secure and user-friendly way to grant SSH access and how to start using it, you should read our article If you're not using SSH certificates, you're doing SSH wrong.

How are OpenSSH certificates different from X.509 certificates?

At first glance, you might think X.509 and SSH certificates are interchangeable. After all, both involve public key cryptography, identity verification, and a certificate authority (CA). But they’re designed for entirely different use cases.

OpenSSH uses a custom certificate format, completely separate from X.509. If you want to use SSH certificates, you’ll need an SSH-specific CA—an X.509 CA won’t work.

That said, RFC 6187 proposes a way to use X.509v3 certificates for SSH authentication, but it’s uncommon and overly complex to set up.

Use Cases: SSH vs. Everything Else

SSH Certificates are purpose-built for SSH authentication—nothing more, nothing less. X.509 Certificates on the other hand are designed to be ubiquitous. They can be used for:

Certificate Structure:

X.509 certificates come with numerous options and complex encoding rules, including a hierarchical chain of trust (Root CA → Intermediate CA → End-user certs), extensions, key usages, policies, and strict encoding formats.

SSH certificates, in contrast, are intentionally minimalist. There’s no hierarchical chain because the SSH CA is self-contained, using a simple key-value structure instead. This means less overhead, reduced complexity, and fewer attack surfaces—making SSH authentication both streamlined and secure.

Here’s what a decoded SSH user certificate looks like:

$ step ssh inspect id_ecdsa-cert.pub
id_ecdsa-cert.pub:
        Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate
        Public key: ECDSA-CERT SHA256:O6M6oIjDm5gPm1/aTY619BgC3KSpS4c3aHVWxYh/uGQ
        Signing CA: ECDSA SHA256:EY2EXJGoPv2LA6yEbjH+sf9JjG9Rd45FH1Wt/6H1k7Y
        Key ID: "linda@example.com"
        Serial: 4309995459650363134
        Valid: from 2022-07-11T14:50:01 to 2022-07-11T18:50:01
        Principals:
                linda
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

And here's what a decoded X.509 client certificate looks like:

step certificate inspect https://smallstep.com
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 312048233971325841563421249287934957707544 (0x39506ffca33cfa15b5325cace3c6c45e118)
    Signature Algorithm: SHA256-RSA
        Issuer: C=US,O=Let's Encrypt,CN=R3
        Validity
            Not Before: Jun 6 07:05:01 2022 UTC
            Not After : Sep 4 07:05:00 2022 UTC
        Subject: CN=*.smallstep.com
        Subject Public Key Info:
            Public Key Algorithm: ECDSA
                Public-Key: (256 bit)
                X:
                    98:e4:b1:ce:2f:54:13:50:ac:af:d0:31:54:79:12:
                    0c:48:83:23:0e:c3:92:92:5e:19:20:b0:a9:f1:5d:
                    63:a8
                Y:
                    29:0d:33:d7:6a:ab:c8:d0:20:03:15:0d:9f:62:8a:
                    b5:37:ff:2b:2c:ef:60:82:b5:fc:a3:b8:9d:c8:f6:
                    70:cd
                Curve: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                Server Authentication, Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                09:5C:5C:F4:77:93:82:7E:E2:9E:C8:3A:EE:CD:4D:40:63:E0:85:67
            X509v3 Authority Key Identifier:
                keyid:14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6
            Authority Information Access:
                OCSP - URI:http://r3.o.lencr.org
                CA Issuers - URI:http://r3.i.lencr.org/
            X509v3 Subject Alternative Name:
                DNS:*.smallstep.com, DNS:smallstep.com
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
            RFC6962 Certificate Transparency SCT:
                SCT [0]:
                    Version: V1 (0x0)
                    LogID: QcjKsd8iRkoQxqE6CUKHXk4xixsD6+tLx2jwkGKWBvY=
                    Timestamp: Jun 6 08:05:01.371 2022 UTC
                    Signature Algorithm: SHA256-ECDSA
                      30:45:02:21:00:8e:77:7a:d9:bf:5c:50:59:60:10:bc:2d:c0:
                      f8:6e:9b:51:1d:31:85:4c:11:fe:89:10:ae:de:5c:e1:d7:0c:
                      a1:02:20:3a:d2:1b:78:67:2c:01:7b:04:07:45:3d:34:c8:30:
                      25:23:fe:f8:1e:ce:74:41:00:a0:88:64:32:de:4a:97:c9
                SCT [1]:
                    Version: V1 (0x0)
                    LogID: RqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUc=
                    Timestamp: Jun 6 08:05:01.416 2022 UTC
                    Signature Algorithm: SHA256-ECDSA
                      30:45:02:20:6a:ca:bb:ec:e6:94:86:2b:2d:c2:57:5a:3c:f0:
                      c5:a1:c2:66:ce:eb:f3:83:4c:c3:94:04:31:57:5e:88:b0:e6:
                      02:21:00:e1:86:6e:0b:d0:c4:5f:18:1e:08:0c:a8:0f:8b:e0:
                      4a:da:b0:a3:33:b4:8f:ae:3a:57:91:aa:13:5d:a6:c3:c2
    Signature Algorithm: SHA256-RSA
         88:a3:d8:fb:86:33:83:a7:4c:cd:cc:e3:f2:f8:04:bf:f0:34:
         1c:f8:2f:f3:09:ec:0c:39:6a:96:f4:15:62:f6:7e:20:50:75:
         e2:f6:c3:79:69:f3:7a:78:71:83:7a:28:d0:c4:51:05:77:57:
         bc:5a:40:58:d0:1d:0e:36:5f:f4:2a:e7:70:7d:70:2f:0f:b1:
         91:f1:31:d2:bd:7d:e8:0b:c3:f9:b1:f3:81:08:b3:cc:a7:0a:
         7c:63:67:97:5c:2b:12:48:7b:39:1c:a0:6c:ae:7d:df:63:76:
         0a:40:27:ca:6a:99:d5:7d:67:d2:29:77:85:bf:b3:19:57:5f:
         c2:23:f4:67:c7:09:8b:d6:c4:fd:01:7e:78:66:eb:58:4f:2d:
         87:60:90:d4:27:b5:69:60:f4:ad:91:51:35:eb:25:01:0a:27:
         47:16:eb:47:18:5a:6e:28:e4:d1:5e:f1:78:81:e7:fa:e6:e4:
         45:a9:06:c5:d4:a6:95:97:58:57:1c:eb:d3:b9:e8:c7:c0:52:
         70:88:d4:71:c1:81:ca:9c:41:e0:f4:a0:88:0d:dd:18:b2:68:
         87:52:65:ea:3a:27:c1:d1:76:8c:61:b5:47:b5:e7:63:38:bb:
         3e:0d:f7:46:f3:00:96:91:df:d2:aa:7e:d4:50:63:79:32:4e:

Trust Model: Chained CAs vs. Direct Trust

X.509 follows a hierarchical trust model, where a Root CA signs Intermediate CAs, which then issue end-user certificates, requiring clients to verify the full certificate chain before trusting a certificate. While effective for the public internet, this approach is unnecessarily complex for SSH.

SSH certificates, in contrast, use a direct trust model, where each host and user certificate is signed directly by the SSH CA. Clients and servers only need to trust a single CA key, eliminating the need for intermediate CAs, certificate chains, or complex validation processes—making authentication faster, simpler, and easier to manage at scale.

Smallstep Does SSH Certificate Authentication Right

OpenSSH certificates solve the biggest problems with SSH authentication—eliminating TOFU, enforcing short-lived credentials, and drastically simplifying key distribution. But setting up a certificate authority (CA) can feel like a heavy lift.

That’s where Smallstep comes in.

We know that one of the biggest headaches about using certificate-based authentication is setting up and managing a CA. With Smallstep’s open-source tool, step-ca, you can easily set up an SSH CA to issue short-lived certificates for users and hosts. You can also leverage your existing OIDC flow to authenticate users and automate certificate issuance—eliminating manual key management.

For teams that don’t want to manage their own CA, Smallstep SSH is a self-service, managed solution that simplifies everything—just $3/month per host. Get started today.

To learn more about SSH best practices, read our other blog posts on SSH:

Linda is a wannabe guitarist, who reads African literature or fiddles with a tennis racket to unwind while navigating the daily grind of helping growth-stage tech startups drive adoption and awareness of their products through tailored content strategies that translate concepts from arcane technical domains into plain and accessible language.