Last Updated on 25/05/2022 by Patryk Bandurski
In many projects that I participated in, mutual TLS was a first choice to secure some of the experience APIs. Two-way TLS is great in proving that two sides are known to each other via the exchange of client certificates. Let’s see how it works in CloudHub when we are leveraging Dedicated Load Balancer.
Architecture
Case
In our case, we have MuleSoft Dedicated Load Balancer. The client would like to secure salesforce and payment gateway communication with mutual TLS. As you can see on the diagram below, we have three client certificates installed on DLB.
- Test Team – client certificate of Integration Testing Team
- Payment Client – client certificate of a payment gateway
- SFDC Client – client certificate of a salesforce instance
We expect that Salesforce calls Salesforce EAPI with the SFDC client certificate, and Payment gateway calls Payment Gateway EAPI with the Payment Client certificate. Our testing team can call both APIs with the same Test Team client certificate.
Configuration
I have described how to set up two-way TLS on DLB in this article. You find there a walkthrough. It is still up to date, although I wrote it in 2020 :).
Consequences
The solution seems alright, but you will see that something is not right after a minute. Imagine that something went wrong, and the Payment Client starts calling Salesforce EAPI. Of course, it should not happen, but what if? In this case, traffic will reach Salesforce EAPI with a successfully validated client certificate. In other words, the Payment Client can call it.
Custom API Policy
I thought about how to add an extra layer of protection. The intuitive approach was to introduce API Policy between DLB and API. So I prepared my custom API Policy called Validate Certificate DN policy. The source code for your reference and use is here on my Github account.
Case
The case is very similar to the previously described one. We add an API policy to allow only a subset of client certificates to call specific APIs. For example, Salesforce EAPI should be reached only by consumers with SFDC client and Test Team client certificates.
The API Policy will validate by comparing two headers computed by DLB: x-ssl-client-verify and x-ssl-client-dn. The first header would contain information if the client certificate was successfully validated on DLB. The second one contains the DN of the provided client certificate. The policy will validate DN for only SUCCESS in x-ssl-client-verify header.
Configuration
Installation of the custom Policy is described in README.MD file in the repo. After successful installation, let’s add the policy to my API.
Once you are in your API, go to Policies and click Add Policy button. Pick from the list Validate Certificate DN Policy – like on the screenshot below.
The first parameter is an array of key-value pairs. Where
- Key is the human-readable name of the client certificate, for example, SFDC client
- Value is a Distinguished Name of the client certificate in the format with slashes like in this example /C=PL/O=Patryk Bandurski/CN=ambassadorpatryk.com
Next, you can provide optionally an error status code and error response. The latter one is an expression where you can put DataWeave code. The default response in case of an error looks like this
{ "message": "Bad Client Certificate" }
Here is a sample configuration for the described case.
Outcome
Salesforce can call with SFDC client certificate only Salesforce EAPI. Our internal testing team can call both APIs by using Test Team client certificate.
Summary
Security is one of the crucial pillars of our projects. In the described case, we just add an extra layer of protection on top of MTLS configured on DLB via introducing a custom API Policy. I hope that simplicity of this solution will help you in case you find a similar case in your project.