Client certificates using cfssl

I’m running a few web-based services for myself and close friends. I would prefer to authenticate clients on the webserver level, since that is probably the best maintained component in the stack. Basic auth would be the obvious choice, but using passwords is tedious. Integration with password managers isn’t great and updating password hashes is annoying.

Disclaimer: While I do work in software, I’m not a security expert. But I do know enough that I can tell you that blindly accepting stuff that some person wrote on the internet is a bad idea when it comes to PKIs. Be warned. Have a threat model.

So, I was looking to client certificates for a solution. Could also be an excuse because I’ve been curious about mTLS for a while, but that’s the opposite of a problem :D

So, here’s the experiment I ran:

  1. Set up a public key infrastructure# (PKI) using cfssl
  2. Run nginx with client certificate validation to verify it worked#
  3. Export the certificate for browsers#

Things got easier each step of the way. The main challenge was the severe lack of cfssl documentation, but the only alternatives I found were plain openssl, which is hard to use well, and smallstep, which seemed to assume that I want to run a server of some kind.

After all, things worked and I’m looking forward to deploying this.

Side note about revocations: In a proper production deployment, you’d probably want that server component. If you cannot easily rotate intermediate certificates, e.g. because you have production traffic that you care about, your services need some way to check that a client’s certificate hasn’t been revoked.