Quickstart
Follow this tutorial to start signing everything.
Overview
We’ve provided a Docker image and Docker compose files to get started configuring secure data exchange quickly.
Note: Please see Software to get the necessary software for this tutorial.
- Launch healthKERI RACK and Mirth Connect.
- Create local identifiers with Locksmith
- Connect to RACK Gateways through Locksmith
- Configure Outbound Route
- Configure Inbound Route
- Launch Routing
- Send Test Data
- Verify Results
- Next Steps
1. Launch healthKERI RACK and Mirth Connect
This tutorial will show you how to launch two Gateways and configure them to sign and encrypt all data exchanged between two Mirth Connect integration engine instances.
What is Mirth Connect
What is Mirth Connect
Mirth Connect is an open-source integration engine designed for data exchange in the healthcare industry. It enables communication between disparate information systems by supporting various healthcare data exchange standards, namely, HL7 and FHIR for text based patient health information, and DICOM for medical imaging transfer. Mirth Connect is intended to facilitate the routing, transformation, and filtering of clinical data between different healthcare sectors and their associated information systems. It is used to integrate data from hospitals, clinics, imaging centers, laboratories, and pharmacies, and more. For the purposes of this tutorial, Mirth Connect serves as a stand-in for any given integration engine used in the healthcare sector.
In the rack-docker
repository there is a Docker compose file called mirth-connect-rack-compose-sample.yaml
that can be used to launch two instances of and two instances of Mirth Connect using the following command:
In addition to the two instances of and Mirth, this compose file also creates two temporary containers that create one channel on each Mirth Connect instance that are preconfigured to work with the instances once this tutorial is complete.
After running the docker compose
command above, the channels are created and started. The following output on your terminal window indicates that the all containers are operational and that you are ready to continue the tutorial:
--insecure
option. They should only be used for local testing and experimentation.CESR Files and Out-Of-Band-Introductions
In order for gateways to communicate with each other securely they need to be aware of each other’s key state (the current set of signing keys to use for signature verification and encryption).
We accomplish this connection by exchanging each gateway’s key event log in CESR encoded stream files in an Out-Of-Band-Introduction (OOBI). These files are exported during the rack install
command that created the Docker images and must be exported from each docker container now running a gateway.
To copy these files out of docker containers, use the following commands:
We will be using these files later in the tutorial.
2. Create local identifiers with Locksmith
Our local wallet and secure proxy is called Locksmith. You will use Locksmith for the rest of this tutorial to establish secure connections to the gateways Administration User Interface (AUI).
The first step is using Locksmith is to create and open a Vault that will hold the Identifiers used for the remainder of this tutorial.
Create Vault
After launching Locksmith for the first time, you will be presented with the Vaults menu, on top of which you will find the Initialize new vault button.
Select this button and create a new vault named “Locksmith”:
Open Vault
After creating the Vault, you open it by clicking the drawer icon in the upper right corner of the Locksmith window and selecting the newly created vault:
Create Identifier
Now, let’s create your first Identifier. The gateways were installed into the Docker images with predetermined cryptographic salts for both the identifier as well as the identifier that is authorized to access the . To connect to the gateways, you must create a local identifier with the same salt that each gateway was initialized with.
That salt is DQ7Hzp4faFdbesNx-_a1v
.
From the Identifiers screen, select the Add Identifier button to create your first identifier:
Set the name for the new Identifier as “admin”, then click on Advanced Configuration and copy and paste the salt listed above into the Salt field. Click on the eye ball icon in the Salt field to confirm that you have pasted the correct value.
After you click Add, the new identifier appears in the grid with the name “admin” and the AID of EK4iFDRWMPH2mJ_VSJZt5VgCTg7wupzKX5nipreSOBuR
.
3. Connect to RACK Gateways through Locksmith
Your connection to the for each gateway is secured using the same and technology at the heart of our gateways. To establish a secure connection to each gateway you must load the files copied from the running Docker containers in Step 1.
Create Remote Gateways
Select Remote Identifiers from the menu on the left
Click on Add Remote Identifiers. In the dialog that appears, set the Alias to “Rack1”, then click the File radio button and Browse for the “rack-1.cesr” file exported from the Docker container earlier:
Repeat these steps to connect to the second gateway with an Alias of “Rack2 and the “rack-2.cesr” file.
Once complete, you should have the following 2 Remote Identifiers listed on the screen:
- Rack1 with an AID of
EPIa-VqM9y2EUUMAJ0MAv5AEdDVvaOcFmIxKn5jzIgKk
- Rack2 with an AID of
EJ8Rx6lal6S7mlrhp6OuHkxAizP7N5ufzllu4YIbjjvV
.
Create Proxies
Proxies are the final step required to launch the screens for each gateway. Each proxy will sign and encrypt all communication from your web browser to the gateway and decrypt and verify all data retrieved from the remote gateway.
Select Proxy from the menu on the left, then click the Add Proxy Redirect button to create a proxy. Select “admin” from the Associated Local AID dropdown to use the identifier created in Step 2, then select Rack1 in the Destination Remote AID dropdown. The Target URL and Target Port fields should populate automatically.
Repeat these steps to create a proxy to the second gateway by selecting “Rack2” from the Destination Remote AID dropdown.
Once complete, you should have 2 Proxies listed on the screen with Destination AIDs Rack1 and Rack2. Both proxies should have the same Signing AID.
Launch Proxies
To launch the for Rack1, select the Actions menu for its row in the grid and click on the Launch button. The status will change from Idle to Running. Repeat this step to launch the for Rack2.
Access RACK Gateways
Launching the proxies will open two browser windows, one for each instance. The browsers will display the for each gateway.
4. Configure Outbound Route
We will use the gateway named Rack1 as our Outbound Route. The first pre-configured instance of Mirth, Mirth1, has a channel created to load any files placed in a certain directory and send them to the IP address of Rack1 at port 3333. We will now create an Outbound Route on Rack1 that listens on port 3333 and signs, encrypts, and sends data to Rack2.
Create RACK Identifier
Select Identifiers from the menu on the left of the Rack1 :
Click on Add Identifier. In the dialog that appears, give the identifier an Alias of “Rack1” and set the Number of Signing Keys, Number of Rotation Keys, Signing Threshold and Rotation Threshold to 1
:
Click Save to create an Identifier that is local to this gateway.
Create Outbound Routes
Now we will define the Outbound Route to the Rack2 gateway. First select Outbound Routes from the menu on the left:
Click on the Add Outbound Route button to create the route.
Give the Outbound Route a Name of “To Rack2” (to indicate the data’s destination). Leave the Peer-to-Peer radio button selected, then select the “Rack1” Identifier you just created from the Local Identifier to Secure the Connection dropdown. Leave the Protocol set to “HTTP” and set the Local Port to 3333.
Click Save to create the Outbound Route to Rack2.
Export Introduction
The two gateways will be connected to each other using the same file approach we used to connect Locksmith to each gateway. To establish this connection you will now export an introduction to the Identifier you created for this gateway from the Outbound Route grid.
Open the Actions menu for the Outbound Route you just created and select the Export Introduction menu item. A new file will be saved on your computer named “Rack1-To Rack2.cesr”. We will use this file in the next step.
5. Configure Inbound Route
Rack2 now becomes our inbound gateway. The second pre-configured instance of Mirth, Mirth2 has a channel created is listening on port 5555 for inbound HTTP JSON files that it will write to a local directory.
In this step, we will create an Inbound Route on Rack2 that listens on port 4444 for signed and encrypted data sent from Rack1. No other data will be accepted into this instance of and therefore the Mirth2 instance of Mirth Connect.
Create RACK Identifier
Navigate to the “Identifiers” screen in the Rack2
. Click on Add Identifier.
In the dialog that appears, give the identifier an Alias of “Rack2” and set the Number of Signing Keys,
Number of Rotation Keys, Signing Threshold and Rotation Threshold to 1
:
Click Save to create an Identifier that is local to this gateway.
Connect to Remote Gateway
Because we exported an introduction from Rack1, we are able to create a remote gateway on Rack2 to use during the creation of our Inbound Route in the next step.
Select Remote Gateways from the menu on the left:
Click on Add Remote Gateway, set the Alias to “Rack1” and select the “Rack1-to Rack2.cesr” file exported from Step 4. above.
Click on Save to load the key state and connection information from Rack1 into the Rack2 gateway.
Create Inbound Routes
Now we will define the Inbound Route from the Rack1 gateway. First select Inbound Routes from the menu on the left:
Click on the Add Inbound Route button to create the route.
Give the Inbound Route a Name of “From Rack1” (to indicate the data’s origin).
In the Route Type section, leave the Peer-to-Peer radio button selected, select the “Rack1” Identifier you just imported from the Accept from Remote Gateway dropdown. Select “172.31.0.5” from the IP address / Host Name dropdown and enter 4444 in the Accept on Port field.
In the Forward To section, leave the Protocol set to “HTTP”, then set the destination IP Address / Host Name to “172.31.0.3” and Port to 5555. That IP Address is the static IP address assigned to the Mirth2 instance in the Docker compose file (The channel created in Mirth2 is set to listen for incoming HTTP connections on port 5555).
Click Save to create the Inbound Route from Rack1.
Export Introduction
As we did with the Outbound Route on Rack1 we must export the introduction to Rack2, but this time from the Inbound Route grid:
Open the Actions menu for the Inbound Route you just created and select the Export Introduction menu item. A new file will be saved on your computer named “Rack2-From Rack1.cesr”. We will use this file in the next step.
6. Launch Routing
We will now complete the connection between the two gateways by loading the file from Rack2 into Rack1 and updating the Outbound Route we created in Step 4.
Complete Gateway Connections
Navigate back to the Remote Gateways section of the Rack1 . Click on Add Remote Gateway, then set an Alias of “Rack2” and select the “Rack2-From Rack1.cesr” file created in the last step:
Click on Save to load the key state and connection information from Rack2 into the Rack1 gateway.
Edit Outbound Route
Because we created the Outbound Route first, we were not able to select the destination Remote Gateway. Navigate to the Outbound Routes section of the Rack1 . Select Edit from the Actions menu of the Outbound Route we created earlier and update Send to Remote Gateway to point to “Rack2”
Click Save to complete the route configuration for both gateways.
Launch Routes
Launch this route by selecting Launch from the Actions menu of the Outbound Route named “To Rack2”:
Perform the same operation on the inbound route in the Inbound Routes section of the Rack2 .
Both gateways are now launched as indicated by their status changing from Idle to Running.
7. Send Test Data
As mentioned previously, the Docker compose file launched in Step 1 created 2 instances of Mirth Connect and configured them with Channels that would send data through our newly configured gateways.
Mirth1 has a channel that is looking for any JSON files to be copied into its local /opt/connect/data
directory (mapped to the <rack-docker dir>/examples/data/volumes/mirth1
directory by Docker compose).
When files show up in /opt/connect/data
, Mirth1 will send those files via HTTP to the IP address and Port that Rack1 is now listening on.
To facilitate testing, we have provided 2 directories (<rack-docker dir>/examples/data/fhir-dataset
and <rack-docker dir>/examples/data/fhir-dataset-large
) of sample FHIR data files that can be used to test the new secure connection. We also included a Shell script that will copy the files into the correct local directory to be picked up by Mirth1.
To send test files through the secure connection, use the following command from the <rack-docker dir>/examples
directory:
This command will copy 50 random files from the examples/data/fhir-dataset
directory to the examples/data/volumes/mirth1
directory which will cause Mirth1 to pick up those files and send them to Rack1
Rack1 will, in turn, sign and encrypt every file (the entire HTTP transaction, as a matter of fact) and send the, now secured, data to Rack2, which will decrypt the data and recreate the HTTP transaction to send to Mirth2.
Logging was left at the INFO level so you will see a series of log statements from Rack1 and Rack2 indicating the successful flow of data, similar to the following:
You have sent fully secure data in Zero-Trust between two Mirth Connect integrations instances without SSL!
8. Verify Results
The Mirth2 instance is configured to write the files it receives from Rack1 to its /opt/connect/data
directory (mapped to examples/data/volumes/mirth2
by Docker compose). To verify that the data flowed successfully through all 4 containers, you can check for new files that will now be in examples/data/volumes/mirth2
:
You can also diff those files to see that the full FHIR records have been transferred completely.
If you would like to verify that only signed and encrypted data was sent between the gateways, we recommend adding a Wireshark container to the mirth-connect-rack-compose-sample.yaml
Docker compose file to analyze the network traffic between the 172.31.0.4
and 172.31.0.5
IP addresses.
9. Next Steps
Now that you’ve connected two gateways directly via a Peer-To-Peer connection, you should see one main limitation with this configuration.
At least one gateway will have to listen for incoming connections on a TCP port. While this may be fine for local testing it can be challenging to test gateways on the Open Internet.
In our next tutorial, we will be demonstrating how to connect two gateways using healthKERI Cloud Routers to remove this limitation.
Stay tuned for our next walkthrough. For questions or inquiries, contact info@healthkeri.com.