I do not mean simply putting the public RSA key of a x.509 certificate into ~/.ssh/authorized_keys - I'm looking for a way to set up a ssh such that x.509 certificates signed by a pre-defined CA will automatically be granted access to the linked user account. RFC 6187 seems to suggest such a functionality, but I can't find any documentation on this, or whether it is implemented in OpenSSH at all.

Here's a more elaborate description of what I want to do:

  • A CA ("SSH-CA") is set up
  • This CA is used to sign user certificates with keyUsage=digitalSignature (and maybe the id-kp-secureShellClient extendedKeyUsage field)
  • This certificate can now be used to log in on a server. The server does not require the public key being present in the authorized_keys. Instead, it is set up to trust the SSH-CA to verify the public key and signature of the certificate (or certificate chain) and the username/UID (probably directly in the subjectAltName field, or maybe using some server-side mapping) before the usual RSA authentication takes place

So, (how) can this be achieved with OpenSSH, and if it requires a patch how can client-side modifications be kept minimal?

As an alternative I guess one could also use any S/MIME certificate plus a username to email-address mapping, without requiring an own CA. The client could also still use only the private RSA key and a certificate server is used obtain a certificate from a public key, additionally offering the possibility to use PGP certificates as well (e.g. via monkeysphere) without the user requiring any knowledge about all this as long as they simply provide a public key.

If it's not natively possible, I guess I could come up with a semi-automatic "implementation" of this by letting a script on the server automatically check a somehow else submitted certificate via openssl (or gnupg) and have the public key be put to the respective user's authorized_keys file - although at that point I am probably more or less re-doing the monkeyshere project...


4 Answers 4


OpenSSH does not officially support x.509 certificate based authentication:

The developers have maintained a stance that the complexity of X.509 certificates introduces an unacceptable attack surface for sshd. Instead, they have [recently] implemented an alternative certificate format which is much simpler to parse and thus introduces less risk.


OpenSSH just uses the low-level cryptographic algorithms from OpenSSL.

However Roumen Petrov publishes OpenSSH builds that do include X.509 support, and you could try with those.

X.509 certificates can [be] used as "user identity" and/or "host key" in SSH "Public Key" and "Host-Based" authentications.

Roumen Petrov's builds can be downloaded via this page.

Here's a Debian how-to for SSH with authentication key instead of password that might also prove useful in setting up your OpenSSH to accept x509 PKI for user authentication.

  • 3
    The Debian link is just about the usual key setup, but Roumen Petrov's build sounds like the solution Feb 19, 2013 at 7:29
  • 2
    Please be careful with Roumen Petrov's build and do not reuse the same x509 certificate for ssl/https. Bugs like 3-Shake show that it is hard to use crypto securely within just the SSL protocol. Security of SSH implementations is never tested in this SSH-SSL key-reuse scenario!
    – user185953
    Mar 14, 2019 at 16:37

Native certificate-based authentication is available in unmodified upstream OpenSSH. It is not, however, based on x.509.

First, generate your CA:

ssh-keygen -f ssh-ca

Next, install your CA key in .authorized_keys with a cert-authority prefix:

echo "cert-authority $(<ssh-ca.pub)" >>.ssh/authorized_keys

From that point, whenever a key is generated by a user:

ssh-keygen -f real-key

...the public portion can be signed by your SSH CA, whereafter it will be trusted by the server without that key itself being added to authorized_keys:

ssh-keygen -s ssh-ca -I identifier_for_your_real_key_goes_here real-key.pub
  • 1
    Thanks, I never read about this despite it being available since apparently 5.4 from 2011... github.com/cloudtools/ssh-ca might be of interest then. I'll try and check this sometime, in which case you'd deserve the checkmark Oct 9, 2014 at 4:37
  • Absolutely incredible! I'm surprised I've never seen this done before!
    – user97193
    Mar 22, 2019 at 16:56
  • It works for known_hosts too; one can put a CA in /etc/ssh/ssh_known_hosts for one's own domain, sign the host keys on the various servers with that CA, and then never again have a prompt asking a user to manually verify (or, more realistically, punt on manually verifying and assume) that a given host key for a server in that domain is valid. Mar 22, 2019 at 21:11
  • (Of course, one needs to be able to distribute updates to that ssh_known_hosts with revocations for compromised host keys, but... them's the breaks). Mar 22, 2019 at 21:12
  • 3
    I believe this answer provides OpenSSH certificate format, and not X.509 certificate format. X.509 certificate format is detailed in RFC 6187. Also see ssh-keygen and writing user certificate in X.509 format? on SuperUser.
    – user29925
    Jul 15, 2019 at 15:58

With OpenSSH it's not possible. As said by @TildalWave you need to use the fork from Roumen Petrov PKIXSSH.

Once you have your X509 certificate you don't need to add the public key on the authorized_keys file.

You need to configure two things in the server side:

  • Add the certificate for the CA in the directory set by CACertificatePath directive in sshd_config file (normally /etc/ssh/ca/crt, I think) with a link for the hash of the certificate.

    For creating the link use openssl. Supposing the CA certificate has been copied under /ect/ssh/ca/crt/ca.crt the commands will be:

cd /etc/ssh/ca/crt/
ln -s ca.crt `openssl x509 -in ca.crt -noout -hash`.0
  • Add the "subject" information of x509 certificate to the authorized_keys file of the user (in destination server)

    Suppose the private key and the X509 certificate of the user is in ssh/id_rsa to get the subject run in the client:

openssl x509 -noout -subject -in .ssh/id_rsa

And them on the server, add this line with the prefix x509v3-sign-rsa subject= to the authorized_keys.

This line will have a content similar to this one:

x509v3-sign-rsa subject= /C=ES/ST=Pontevedra/L=Vigo/CN=testssh/emailAddress=josemanuel@ciges.net

As we can see, the authentication is really made trusting the CA for any valid x509 certificate from the user. We could generate a new certificate and it will be accepted with no intervention on server side.

After struggling for a few days I have written a post explaining the full process on a blog I have just deployed. You can read it at "OpenSSH with X509 certificates HOW TO".

  • Thanks for the edit!
    – schroeder
    Mar 26, 2020 at 13:51

CA Signed SSH keys

When you want to manage user's access out-of-bound, then you don't want to install their public key in authorized_keys files on the servers they need to access. Neither do you want to manage personal accounts, but instead use a principal (functional account i.e. admin) and grant a lease on it.

You can create a Certificate Signing Authority for Secure Shell (different from X509 TLS/SSL) simply by creating an ssh keypair. The CA's public key is installed on all servers, and that is the only file that needs to be there. (You can have 2 CA keys in the file or more if you need.)

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/ca_ssh
cat ~/.ssh/ca_ssh.pub

Copy this file to the servers and add it to /etc/ssh/sshd_config:

TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pub

Granting Access

To sign Fred's public key (fred.pub) to grant one week access to the server as admin and log as staff in /var/log/secure, run this command and send the fred.pub-cert file back to Fred.

ssh-keygen -s ~/.ssh/ca_ssh -I staff -n admin -V +1w fred.pub

Revoking keys

Add public keys of people that should no longer login during their lease to playbook_dir/files/ssh/revoked_keys

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.