I have enabled MTLS on APIGEE northbound. A request with a client certificate is getting authenticated as far as it has the same trusted root as the certificate present in the truststore.
For instance, test1.northbound.com and test2.northbound.com have the same trusted root certificate.
I have added test1.northbound.com to the truststore and mapped it to the virtual host. In the testing, I found that I am able to use either test1.northbound.com or test2.northbound.com to get authenticated. I was expecting only test1.northbound.com would get authenticated.
Question: Is it possible to authenticate a specific certificate, like in the above scenario only test1.northbound.com should get authenticated.
Solved! Go to Solution.
Yes it is possible
What version of Apigee are you using here?
The Truststore is designed to work in the way you understand: Certificates that you place into the Truststore are treated as trusted roots. When mTLS clients connect and conduct their side of the TLS handshake, Apigee will verify trust of the cert chain that the client presents, based on the trusted roots in the Truststore.
If you place ONLY the cert for test1 into the Truststore and then use a client that presents a cert chain for test2, and no cert for test1 , then Apigee should reject that client. But I am not clear whether this is what you have done. BTW I am avoiding the use of .northbound.com in the names for the hypothetical client-side certificates I am talking about, because in general clients do not have DNS names. DNS names are associated with IP addresses and indicate servers; things that receive inbound requests. It makes sense for a server to have a name like "server1.northbound.com" and a corresponding certificate, but a client should not have such a name, nor a certificate for a name like that. A cert for a client might include a set of "Subject alternate names" (SANs) for the party identified by the certificate. This might be an email address or a URI (an identifier, not necessarily a locator. Eg this would be fine as a SAN for a client app: urn:my-company:app:9783-16-1484)
If you have both the cert for test1 as well as rootca, in the truststore, where rootca is the signer of test1, then both of those will be trusted roots. In this case if a client presents the cert for test2 , and that cert is signed by rootca, then Apigee will treat the cert for test2 as trusted. On the other hand if the Truststore contains ONLY the cert for test1, and the client presents test2, then Apigee should reject that cert as untrusted.
In general it is not a Greta idea to insert leaf certs (like test1) into the Truststore, for any system. It may make sense but usually not. The recommendation is to use root CAs in the truststore . These will be self-signed certs that belong to certificate authorities. In this case you would rely on the application to allow/deny the client's cert. For example you can have your API proxy inspect the fingerprint of a cert and accept / reject the request based on that fingerprint.
There are some gotchas. When you update Truststores in older versions of Apigee you may need to stop/restart the router in order to get the new settings to be applied.
I have added whole chain to the trust store.
"The whole chain" is not what you want to add to a Truststore. You want to add trust roots. These are generally certificates for root CAs.
The way TLS negotiation works: during handshake, the client sends the trust chain to the server (in this case Apigee). Apigee evaluates trust of the entire chain, against the trust roots in the TrustStore. This means Apigee checks ...
You do not want chains or leaves or intermediate certs in your trust store. It should hold trust roots.
@SanalNaroor wrote:
Did you mean to say we could additionally check SAN for this purpose.
I mean if you want to distinguish between test1 and test2, then you could introduce checks in your API proxy to examine fingerprint, or SAN, or something else from the client's certificate. Adding a leaf cert into the Truststore is generally not a good idea; but you can have this sort of discrimination - I want to allow test1 but not test2 - in your API proxy, if you want.
Yes it is possible
What version of Apigee are you using here?
The Truststore is designed to work in the way you understand: Certificates that you place into the Truststore are treated as trusted roots. When mTLS clients connect and conduct their side of the TLS handshake, Apigee will verify trust of the cert chain that the client presents, based on the trusted roots in the Truststore.
If you place ONLY the cert for test1 into the Truststore and then use a client that presents a cert chain for test2, and no cert for test1 , then Apigee should reject that client. But I am not clear whether this is what you have done. BTW I am avoiding the use of .northbound.com in the names for the hypothetical client-side certificates I am talking about, because in general clients do not have DNS names. DNS names are associated with IP addresses and indicate servers; things that receive inbound requests. It makes sense for a server to have a name like "server1.northbound.com" and a corresponding certificate, but a client should not have such a name, nor a certificate for a name like that. A cert for a client might include a set of "Subject alternate names" (SANs) for the party identified by the certificate. This might be an email address or a URI (an identifier, not necessarily a locator. Eg this would be fine as a SAN for a client app: urn:my-company:app:9783-16-1484)
If you have both the cert for test1 as well as rootca, in the truststore, where rootca is the signer of test1, then both of those will be trusted roots. In this case if a client presents the cert for test2 , and that cert is signed by rootca, then Apigee will treat the cert for test2 as trusted. On the other hand if the Truststore contains ONLY the cert for test1, and the client presents test2, then Apigee should reject that cert as untrusted.
In general it is not a Greta idea to insert leaf certs (like test1) into the Truststore, for any system. It may make sense but usually not. The recommendation is to use root CAs in the truststore . These will be self-signed certs that belong to certificate authorities. In this case you would rely on the application to allow/deny the client's cert. For example you can have your API proxy inspect the fingerprint of a cert and accept / reject the request based on that fingerprint.
There are some gotchas. When you update Truststores in older versions of Apigee you may need to stop/restart the router in order to get the new settings to be applied.
I have not added the leaf certificate to the trust store rather, I have added whole chain to the trust store. So request with either test1 or test2 certificate should authenticate. I don't think adding just the leaf certificate to truststore is a good option either. Did you mean to say we could additionally check SAN for this purpose.
I have added whole chain to the trust store.
"The whole chain" is not what you want to add to a Truststore. You want to add trust roots. These are generally certificates for root CAs.
The way TLS negotiation works: during handshake, the client sends the trust chain to the server (in this case Apigee). Apigee evaluates trust of the entire chain, against the trust roots in the TrustStore. This means Apigee checks ...
You do not want chains or leaves or intermediate certs in your trust store. It should hold trust roots.
@SanalNaroor wrote:
Did you mean to say we could additionally check SAN for this purpose.
I mean if you want to distinguish between test1 and test2, then you could introduce checks in your API proxy to examine fingerprint, or SAN, or something else from the client's certificate. Adding a leaf cert into the Truststore is generally not a good idea; but you can have this sort of discrimination - I want to allow test1 but not test2 - in your API proxy, if you want.