Tuesday, May 30, 2017

Mule Credential Vault

1.0 Overview

Mule credential vault is a feature where users could encrypt the values of a property file. For instance if, credential vault is implemented in your mule project then you have a property file that looks like the following (Figure 1.0).

There is two ways to implement Mule Credential vault. You can either use the out of the box method or you could implement a customized method.

The results of the implementation would be the same that is you will have an encrypted property file. The only difference is how the encrypted key is supplied for decryption of the property file during runtime.
Before you can use the mentioned feature you would need to install the “Anypoint Enterprise Security Module”.
If you are building maven mule projects you would also need to include the following snipped into your POM.xml file.



1.1  The Concept

The Mule Credential vault constitute of 3 things as illustrated by figure 1.1.

Figure 1.1

There is 3 possible ways to implement the mentioned constituent components, and they are as illustraited at figure 1.2, (the diagrams are reference from the MuleSoft’s documentation of the Credential Vault).

Figure 1.2

2.0 Use Case of OOTB Credential Vault

Here in this article I will be talking about the OOTB way to encrypt your property files, as with all the articles I write it is easier for me to illustrate the use case of a particular design/feature by ­­enacting a hypothetical scenario.

Let’s say that you are tasked with developing a façade/proxy Web API, where you relay request to the underlying real API. The underlying API that you have been asked to façade requires a “client id” and a “client secret” in order to authorize its usage. The following picture shows a high-level summary of this requirement.

Figure 2.0

2.1 The Actual API

For the sake of illustrating the usage of Credential Vault we will be storing the client id and client secret required by the Actual API illustrated in Figure 2.0.
This section will illustrate briefly how this back end API works. I have reused the “MuleSoft Cloudhub tutorial API” that allows users to query for fictitious flight schedules. The following is the link to the API.

In order to test the availability of this API, you need to launch post man and key in the following parameters, select GET as the HTTP operation and click send. This API will give you a JSON array of flight schedules.

The following is the HTTP parameters to be keyed in to the parameter fields.
·         "client_id":"d1374b15c6864c3682ddbed2a247a826"
·         "client_secret":"4a87fe7e2e43488c927372AEF981F066"

3.0 Steps to lock your property files in the Credential Vault

The following Figure 3.0 depicts how your final solution will look like. The Mule flow looks exactly like the requirements illustration at Figure 2.0.

Figure 3.0

3.1 Creating the Global Security Placeholder

You would also need to create the following global mule configuration element as per the following diagram “Figure 3.0.a”.

Figure 3.0.a
I have set a global secure place holder to decrypt my encrypted property file the first field (1) is the encryption algorithm that you will use to encrypt your property file. The second field (2) is the additional encryption parameter that you have used to encrypt your file.
Parameter number (3) is the actual key that you are using to encrypt the values of your property, and lastly argument number (4) is the file that you are encrypting, notice the ${env} this is configured so that it gives me the flexibility of switching configurations between environments.

3.2 Encrypting the property files

The following illustration depicts the different keys I have used to encrypt different environment files (Figure 3.0.b).

Figure 3.0.b
The following steps will walk you through on encrypting the property values.
1)      Navigate to the property file that you want to encrypt, then right click, select open with > Mule Properties Editor.
2)      Click on the green cross as per the following depiction

3)      When prompted with the “Add a new property” dialog key in the client_id

4)      Now click on the encrypt button, and you will be prompted with a “Setup encryption information” dialog, in the first Algorithm dropdown select “Blowfish” and then key in “mule123dev”, this value from now on will be your encryption and decryption key.

5)      Right after you click on the OK button, you will see that your property value is encrypted.

6)      When you click ok again, you will see that you value is populated in the property editor window.

7)      At the bottom of the property editor console you will be able to see two tabs, the “Table editor” tab and the “Text editor” tab, you can click on the text editor tab to get a plain text view of your property file, but you must only use the table editor to encrypt your values.

3.3 Testing your encrypted property files

Now that you have successfully configured your application to have encrypted property files is time to test it. In an actual production scenario, you will need to configure the following to the “mule-app.properties” file.
Figure 3.3.a

This is so that your mule application will ask for the following parameters during run time.
-          “env” – to specify the environment that you want to run your mule application in, this is really handy as the property place holder (Figure 3.0.a parameter number 4) that you have specified previously will select the correct property file based on what you have entered into this parameter
-          “cre.vault.key” – this is to specify the key that you have used to encrypt your property values, so that your mule application’s secure property place holder (Figure 3.0.a parameter number 3) would use it to decrypt the key values during run time.
Figure 3.3.a depicts the values you will set to force your mule application to request for a command line parameter when you try to start it, if the key value is not specified your application will fail to run, but if you want to test run your application in Anypoint Studio, then your “mule-app.properties” file would need to look like the following.

Figure 3.3.b
Once you start your application via Anypoint studio head over to Postman.

Figure 3.3.c
At Postman browse to local host port 8081, as per depicted by figure 3.3.d, without the need to key in any client_id and client_secret parameter you have successfully queried for flight schedules, you have successfully façade the back end API.

Figure 3.3.d

4.0 Things to look out for when implementing Credential Vault

If you are reading this article and if you also happen to be developing the mule application for a while you would already have a pre-existing property place holder, as depicted in Figure 4.0.a below.

Figure 4.0.a
Configurations like this will trip you up. Let’s see what happens when you have both the normal property place holder and the security place holder pointing to the same file, let’s test it. In order to demonstrate what I mean, you have add the normal property place holder save the mule configuration file and restart the mule application.
If you test with Postman you will get a 403 error.

Figure 4.0.b

If you look under the hood of Anypoint Studio console log you will see the following log.

Figure 4.0.c

Figure 4.0.c shows that your mule application do not know how to decrypt the client_id and client_secret value. The normal property place holder has more precedence compared to the secure property place holder. This issue really did trip me up, it took me half a day to sort this out.
If you have a few property files and need a property place holder for them you could use the created secure property place holder, you just need to add all the property file names as comma separated list (as per depicted in Figure 4.0.d).

Figure 4.0.d

5.0 Conclusion

-          There can only be one – in section 4.0 I have demonstrated the issue if you use both the secure property place holder and the normal property place holder in your mule application. It is best to use just either one, and it doesn’t really matter if you have values that do not need to be encrypted, the secure property place holder is capable of reading unencrypted value during run time as well.
-          “mule-app.properties” settings – this file would need to be set up differently if you are testing/running your mule application in Anypoint studio versus testing/running your mule application in an actual mule EE runtime.
-          Source Code again is available at the following git hub repository, clone it and have a play with it, the only way to learn and internalize something is to have a play with it.

Wednesday, May 3, 2017

MuleSoft's Scope of Session and Flow Variables

1.0 Overview

We need to know the life of session variables (sessionVars) and flow variables (flowVars) in MuleSoft. If you are like me, aiming to get the "MuleSoft Certified Developer - Integration Professional," the concept of variable scopes needs to be clear in your mind. Some of the questions you might have would be like the following.

1.1 The Question That Tests Our Understanding

Based on Figure 1.0 below, what flow and session variable is accessible in the response scope of "Flow A" and "Flow B?"

2.0 Crystalizing Variable Scope Behaviours

In order to find out, we could create a response scope in both flow A & B, we could modify it to be like Figure 2.0. I have put in 4 logging to print out flow and session variables in both the request and response scope of flow A and B.

I have keyed in the following MEL expressing in the loggers:-
FLOW <A or B> <Request or Response> Scope Accessible Variables: #[flowVars.flowVarriable1] #[sessionVars.SessionVariable1] #[flowVars.flowVarriable2] #[sessionVars.SessionVariable2]

2.1 The sample code to exemplify the behaviors

These loggers will print out the values of the variables in their respective places. The full mule xml code for this running test program is as per the following:-
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking"
xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="" port="8081" doc:name="HTTP Listener Configuration" />
<vm:connector name="VM" validateConnections="true" doc:name="VM" />
<flow name="FlowA">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP" />
<set-variable variableName="flowVarriable1" value="F1" doc:name="flowVarriable1" />
<set-session-variable variableName="SessionVariable1" value="S1" doc:name="SessionVariable1" />
message="FLOW A Request Scope Accessible Variables: #[flowVars.flowVarriable1] #[sessionVars.SessionVariable1] #[flowVars.flowVarriable2] #[sessionVars.SessionVariable2]"
level="INFO" doc:name="Logger" />
<vm:outbound-endpoint exchange-pattern="request-response" path="testQ" connector-ref="VM" doc:name="VM" />
message="FLOW A Response Scope Accessible Variables: #[flowVars.flowVarriable1] #[sessionVars.SessionVariable1] #[flowVars.flowVarriable2] #[sessionVars.SessionVariable2]"
level="INFO" doc:name="Logger" />
<flow name="FlowB">
<vm:inbound-endpoint exchange-pattern="request-response" path="testQ" connector-ref="VM" doc:name="VM" />
<set-variable variableName="flowVarriable2" value="F2" doc:name="flowVarriable2" />
<set-session-variable variableName="SessionVariable2" value="S2" doc:name="SessionVariable2" />
message="FLOW B Request Scope Accessible Variables: #[flowVars.flowVarriable1] #[sessionVars.SessionVariable1] #[flowVars.flowVarriable2] #[sessionVars.SessionVariable2]"
level="INFO" doc:name="Logger" />
message="FLOW B Response Scope Accessible Variables: #[flowVars.flowVarriable1] #[sessionVars.SessionVariable1] #[flowVars.flowVarriable2] #[sessionVars.SessionVariable2]"
level="INFO" doc:name="Logger" />
You can trigger the mule flow via Postman, by pointing to the test uri, when you click send on postman as per Figure 3.0.

2.2 Result of Code Run

If you run the Mule application the following log entries would be printed.
LoggerMessageProcessor: FLOW A Request Scope Accessible Variables: F1 S1 null null
LoggerMessageProcessor: FLOW B Request Scope Accessible Variables: null S1 F2 S2
LoggerMessageProcessor: FLOW B Response Scope Accessible Variables: null S1 F2 S2
LoggerMessageProcessor: FLOW A Response Scope Accessible Variables: F1 S1 null S2

3.0 Conclusion

A graph representation on the accessible variables in each response and request scope are as depicted in the following Figure 4.0.

To simplify this, look at the following depiction (Figure 5.0). Notice the response scope of "Flow A", the S2 variable is accessible by "Flow A" once "Flow B" returns the control to the calling flow.

From this behavior we can conclude that as long as a session variable is created it can traverse transport and be accessible by the calling flow and vice versa. With this new understanding you could answer certification examination questions confidently, because we can’t dispute the results of our test. As always if you want to understand a core concept in Mule or another technology it is always good to devise a lap or a program to test out it's behavior. There is no better substitute to deliberate practice in gaining new experience.

I have included some references URL in this article, you could read up more about Session and Flow variables via those links.