The CN field on certificates is officially deprecated, and is likely going to be removed at some point in the near future. Now is not the time to start relying on it.
Browser root programs have indicated they’d like CAs to split client and server CAs in the future as well, so there’s some compatibility risk there too but that’s longer term.
Checking SANs on client certificates for a B2B API is relatively common, and is certainly not the worst case. But realistically you’re probably going to have a better time using a private PKI or authenticating with hashes of self-signed certificates, which avoids many issues with parsing and authorization bugs that you may have.
I believe one convention with mtls client certificates is to control the issuance yourself, that way you are checking the cert is valid and known at the same time, or require clients upload the public certs the intend to use.
Cloud API gateways etc usually require you to upload the specific public certs that will be accepted (rather than just matching a name).
You should ideally also use a shared secret or other public/private key pair that you have given the client (and that you can revoke) so you're not just relying on the certificate to authenticate the caller, but that depends on how secure you need things to be, e.g. if you are dealing with private customer data you definitely want more security, if you're just offering a stock ticker data API then maybe not so much.
Also worth stating that mTLS is more than validating a presented certificate, it's an actual conversation whereby you prove that the client holds the private key to the cert that they say they have. Anyone can have the public key cert (e.g. you could download googles public cert from crt.sh | 3144337544l) but only the real key holder can provide the correct answer to prove it holds the private key : Mutual authentication - Wikipedia
Thanks for your input,
Yeah looks like CNs and LetsEncrypt is not a good fit in general.
@webprofusion:
this would be for restricted data.
We do not like the idea of controlling issuance as the secret would have to pass from us to B2B third party creating more challenges regarding the transmission channel like trail, people, encryption
So far, our preferred method is publicly issued certs with 1 year validity or certs issued by third party's internal root CA.
There are many additional authentication mechanisms at play (ip whitelisting, secret headers, JWT bearer tokens etc)
(I don't have any confusion with mutual-tls btw)
Ok, you will likely need to pay for 1yr client certs from a CA and presumably your clients will need to be the ones acquiring those, they will then need to register their cert with you so you can associated it with them.
Personally, I'd run a private CA instead. That way you control certificate lifetime. You could still run a private ACME-enabled CA (using step-ca etc) that issues client certs without you knowing the clients private key. You can host this yourself or use cloud (API proxying) services like smallstep certificate manager.
Are those renewals automated?
If so, then the [1 year / 90 day] timeframe is not relevant.
If it all has to be done manually, then you might want to look into automating it.
[perhaps reusing the same private key could help]
@jple I feel like I see this suggestion a lot everywhere... do you think smallstep would like to make a landing page or FAQ or something about patterns for using step-ca for client authentication?
... because I agree with @webprofusion that Let's Encrypt usually isn't great for client authentication and that step-ca usually is!