I am looking for best-practice advice for building a mutually-authenticated system using certificates. I would like to create a system with multiple IoT devices reporting data to a web server, in which both the server and client need to authenticate each other. I was thinking of using a root certificate authority (a personal one) and an intermediate certificate authority for the server certificate and another one for the client certificates.

Root CA signs intermediate CAs (x2), one signs server certs, one signs client certs.

In the future Root CA may sign another intermdetiate CAs.

Does this makes sense? Or is it better to implement separate root CAs for the server and the clients?

Since I am going to use self signed certs, in order one side to verify the other, do I have to provide root cert to all? or intermediate cert? What happens if one of the devices get compromised? (Revoking?)

Sorry for multiple questions but the follow up questions are related to the main question. How should the cert chain be designed? Which approaches are more secure?


I would deploy simple 2-tier hierarchy with single root and single issuing CA that will issue certificates to both, clients and servers. Unless there are no specific requirements, there is no need to deploy multiple roots or even intermediate CAs. Just keep simple 2-tier.

do I have to provide root cert to all?

yes. Clients will have to trust your root to authenticate server. Server will have to trust your root to authenticate clients.


yes. However, revocation may have big latency. Therefore it may be reasonable to have a local database to record all clients and their basic info. If device gets compromised, update the database (disable device account) to temporarily prevent device from connecting to server until the issue is resolved.


I don't know that there is a single set of "best practices" for doing client-auth since it depends a lot on the details of your environment. You can probably find best practices for setting up a CA for VPN client auth, if that's close enough.

I can give you a list of questions that you should think about in the context of your application. In solving these problems, the question about CA hierarchy may get solved for you.

  • Is there anything differentiating a client from a server? It would be bad if a someone could set up a fake server using a client cert and get other clients to connect to it. There are any number of ways you could solve this: you could use different root CAs for clients and servers, though it may be simpler to put a "I am a client" and "I am a server" Extended Key Usage into the certificate. Note that the more clever methods will require you to write custom certificate validation code on the client and / or server components.

  • How does revocation work? If a client/server needs to revoke their certificate, who do they contact? How will the servers/clients know it has been revoked? How quickly will the servers/clients know it has been revoked?

  • How are you updating client certificates when they expire? (don't pull a Tesla, full twitter thread here)

  • How are you securing the private keys of the CAs? Are they being stored on some sort of hardware token? What happens if the machines hosting the CAs go down? (either temporarily, blocking revocation information from being published, or permanently, losing the CA private keys)

Basically, I think how you set up the CA hierarchy ends up being a side-effect of how you address the other security considerations ;)

  • 2
    Extended Key Usage distinguishes client vs server and should already be implemented in any decent SSL/TLS stack -- although depending what your 'Things' are they not have decent SSL/TLS stack. On the bright(?) side, at least Tesla didn't set all the clocks back a few weeks to fake before-expiration -- I've seen people do that. – dave_thompson_085 Aug 28 '18 at 3:14
  • @MikeOunnsworth can't agree with your last statement. Hierarchy question is not less important than ones you expressed. It affects the whole operational and maintenance strategy, including disaster recovery, revocation configuration, etc. Also, in most cases two separate roots is an overkill and greatly increases maintenance and operational efforts/costs. Single root is good enough for most deployments. – Crypt32 Aug 28 '18 at 4:37
  • @Crypt32 Yeah, I think we're saying the same thing: that the hierarchy question isn't one you design for explicitly, and one hierarchy isn't inherently more or less secure than another; instead the hierarchy should be a result of how you solve the other questions. – Mike Ounsworth Aug 28 '18 at 10:38

Your Answer

