(June 2020)<p>I like client certificates, for all the reasons stated in the article. I have recently used them to authenticate API/RPC access for some IoT-ish devices.<p>They work great.<p>Setting up nginx to proxy things through to the backend Go API server was a bit uncomfortable, however.<p>Getting the exact right incantation of `ssl_verify_client`, `map $ssl_client_verify ...` and `$ssl_client_escaped_cert` to achieve the desired effect is nowhere near as straightforward as it should be. Then on the backend, you have to be very mindful of what nginx has and hasn't done with respect to verification of the proxied client certificate.<p>If you are not well-versed in mutual TLS, then I can easily see how this could go horribly wrong.<p>Drew argues that OAuth is often implemented poorly. I agree, but I don't think that client certificates are less prone to implementation problems.
I’ve used client-side certs at a reasonable scale for API’s.<p>The only downside I saw, setting up an internal CA and no matter how many warnings you send someone will always forget to renew the cert at some point.<p>They work really well and I think the only reason we don’t see them more is simply because your favourite http library likely didn’t support them.<p>They are far simpler than JWT for auth.<p>I think for internal service-service x.509 would be my preference. Also if writing internal web applications they’d be a good choice as can issue users certs and they get sso.