Announcements
This site is in read only until July 22 as we migrate to a new platform; refer to this community post for more details.
Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

MTLS-how to authenticate only a specific certificate in Apigee Northbound

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 Solved
0 3 343
2 ACCEPTED SOLUTIONS

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. 

 

View solution in original post

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 ...

  • is the top cert in the chain not expired, valid, appropriate key strength, appropriate key usage?
  • is the top cert in the chain signed by the next cert in the chain?
  • Is the 2nd cert in the chain not expired, valid, appropriate key strength and usage?
  • is the 2nd cert in the chain signed by the next cert?
  • .... and so on , until the last link in the chain
  • is the last link in the chain signed by a trusted root cert that is found in the trust store?

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.

View solution in original post

3 REPLIES 3

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 ...

  • is the top cert in the chain not expired, valid, appropriate key strength, appropriate key usage?
  • is the top cert in the chain signed by the next cert in the chain?
  • Is the 2nd cert in the chain not expired, valid, appropriate key strength and usage?
  • is the 2nd cert in the chain signed by the next cert?
  • .... and so on , until the last link in the chain
  • is the last link in the chain signed by a trusted root cert that is found in the trust store?

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.