Certficate pinning: should I pin the leaf or intermediate?

You can pin leaf, intermediate CA, or root CA. All will work, but each comes with a usability / security tradeoff depending on the details of your setup.

The article you link actually gives a fairly good run-down of the differences:

Leaf certificate. By pinning against your leaf certificate you are guaranteeing with close to 100% certainty that this is your certificate and thus the chain is valid. Leaf certificates tend to have a short expiry time and if, for instance, the SSL certificates are re-issued because the private key is compromised your app will be bricked until you can push an update out. Of course the same may also be true if you frequently cycle your certificates.

Intermediate certificate. By pinning against the intermediate certificate you are trusting that intermediate certificate authority to not mis-issue a certificate for your server(s). This also has the advantage that as long as you stick to the same certificate provider then any changes to your leaf certificates will work without having to update your app.

Root certificate. By pinning against the root certificate you are trusting the root certificate authority as well as any intermediaries they trust not to mis-issue certificates. Often the root and intermediate authorities are the same company in which case there’s not much difference in the number of people you are trusting, however that’s not always the case.

In addition to what the article mentions, I'll say that then you pin a cert, you are removing the CA's ability to revoke that cert because your app trusts that cert implicely and will never go looking for status info for it. By that logic, pinning a CA (intermediate or root) has the advantage that when your leaf cert expires, gets hacked because you accidentally publish the private key on github, or whatever, you can easily ask the CA to revoke it and issue you a new one. Your app will keep working.

Personally, I would avoid pinning a leaf because you're essentially removing the parts that make a cert a cert: revocation and chaining to a trust root. You might as well do openssl genrsa and pin the public key in your app because you're not really getting any benefit from it being a cert.

That said, when you pin a CA, your app will trust any certificate issued by that CA, possibly to other people. You may be ok with that, maybe because it's your private corporate CA, or you may need to implement extra certificate validation logic to ensure that the cert chains to a pinned CA and the name matches what your app expects (and convince yourself that the CA would never in good faith issue a cert with that name to anyone who isn't you).


Summary: Pinning the leaf, intermediate CA, or root CA are all acceptable practice with some slight pros and cons. Do whatever makes sense for your app.