Business need
Mutual TLS (mTLS) is an authentication method used by Fluid Topics to secure incoming API calls.
Overview
To implement mTLS in an environment, it is necessary to provide a certificate authority delivered by an internal certificate authority (CA). Once the CA created, it is possible to generate as many client certificate as necessary.
It is necessary to use a certificate issued by an internal CA, rather than from a public CA, because their function is fundamentally different. Public CAs are intended for server authentication, while an internal CA is used to check the identity of the user or application accessing an API.
It is recommended to use a secrets manager such as HashiCorp Vault to keep a private key safe.
Procedure
The procedure for mTLS connection requires actions from a user and a CA administrator.
The following steps are for the CA administrator:
The following steps are for the user:
Generate a CA
To establish trust between client applications and Fluid Topics, it is necessary to generate a certification authority (CA). This CA allows the creation of client mTLS certificates.
As a CA administrator, run the commands below in a terminal to generate a CA:
-
Run the following command to set environment variables:
export SUBJECT="/C={YourCountry}/ST={YourStateOrProvince}/L={YourLocationOrCity}/O={YourOrganizationName}/CN={CertificateCommonName}" -
Run the following command to define the
$PREFIXvariable:export PREFIX="{certificate-usage}" -
Run the following command to generate the CA:
openssl req -x509 -newkey rsa:4096 -keyout ./${PREFIX}-mtls-private-key-root-ca.key \ -out ./${PREFIX}-mtls-root-ca.pem -sha256 -days 3650 -nodes -subj "$SUBJECT"
This script generates a .key file and a .pem file, located in the current working directory. Send the .pem file to a Fluid Topics representative for deployment.
The .key file is a private key and should NEVER be shared with anyone. A compromised private key invalidates the security of the mTLS connection.
Example
Below in an example for a fictional company called "Any Org" based in London, England. The use case is connecting Salesforce to Fluid Topics.
-
Set environment variables:
export SUBJECT="/C=UK/ST=England/L=London/O=Any Org/CN=sftofluid-prod-mtls" -
Define the
$PREFIXvariable:export PREFIX="sftofluid-prod" -
Generate the CA certificate:
openssl req -x509 -newkey rsa:4096 -keyout ./${PREFIX} -mtls-private-key-root-ca.key \ -out ./${PREFIX}-mtls-root-ca.pem -sha256 -days 3650 -nodes -subj "$SUBJECT"
Create a certificate signing request
Once the .pem file generated and shared, it is possible to create a certificate signing request (CSR) for each user or application that needs to connect to Fluid Topics via mTLS.
As a user, run the commands below in a terminal to generate a CSR:
-
Run the following command to set environment variables:
export SUBJECT="/C={YourCountry}/ST={YourStateOrProvince}/L={YourLocationOrCity}/O={YourOrganization Name}/OU={YourOrganizationalUnitOrDepartment}/CN={CertificateCommonName}" -
Run the following command to define the CSR's name:
export NAME={TheUsersName} -
Run the following command to create a directory for the CSR:
mkdir ./user-certificate -
Run the following command to generate a private key:
openssl genrsa -out ./user-certificate/$NAME.private.key 2048 -
Run the following command to generate the certificate signing request:
openssl req -new -sha256 -key ./user-certificate/$NAME.private.key -subj "$SUBJECT" -out ./user-certificate/$NAME.csr
Each user must create their own certificate signing request with a paired private key.
The script generates a .private.key file and a .csr file, located in the current working directory. Send the .csr file to the CA administrator who previously generated the CA certificate.
The .private.key file is a private key and should NEVER be shared with anyone. A compromised private key invalidates the security of the mTLS connection.
Example
Below is an example of how the preceding script could be modified using a fake company called "Any Org" based in London, England, for the user John Doe in the engineering department:
-
Set environment variables:
export SUBJECT="/C=UK/ST=England/L=London/O=Any Org/OU=Any Org Engineering/CN=John-Doe" -
Define the CSR's name:
export NAME="johndoe" -
Create a directory for the CSR:
mkdir ./user-certificate -
Generate a private key:
openssl genrsa -out ./user-certificate/$NAME.private.key 2048 -
Generate a certificate signing request:
openssl req -new -sha256 -key ./user-certificate/$NAME.private.key -subj "$SUBJECT" -out ./user-certificate/$NAME.csr
Sign a certificate signing request
The CA administrator can sign the certificate signing request (CSR) and share the signed certificate (CRT) with the user as follows:
-
Run the following command to define the validity period of the certificate:
export VALIDITY={number of days} -
Run the following command to define the name of the signed certificate (use the same name as the CSR):
export NAME="{username}" -
Run the following command to generate a certificate (
.crtfile):openssl x509 -req -CAcreateserial \ -in /path/to/$NAME.csr \ -CA /path/to/{PREFIX}-mtls-root-ca.pem \ -CAkey /path/to/{PREFIX}-mtls-private-key-root-ca.key \ -out /path/to/$NAME.crt \ -days {VALIDITY} -sha256 -
Run the following command to remove the CSR:
rm /path/to/$NAME.csr
After creating the signed certificate in .crt format, the CA administrator sends it to the user. The user can then pair the .crt file with a personal private key to connect via mTLS.
Example
Below in an example for the following fictional values:
- The user is named "John Doe", and The
johndoe.csrfile is located in the/Users/admin/Documentsdirectory. - The organization's CA certificate is named
sftofluid-prod-mtls-root-ca.pemand is located in/Users/admin/Documents. - The private key is named
sftofluid-prod-mtls-private-key-root-ca.keyand is located in/Users/admin/Documents. - The intended output name of the file is
johndoe.crtand its destination is/Users/admin/Documents/. - The intended validity period is 2 years.
Run the following commands:
-
Define the validity period of the certificate:
export VALIDITY=730 -
Define the name of the signed certificate:
export NAME="johndoe" -
Generate a CRT:
openssl x509 -req -CAcreateserial \ -in /path/to/$NAME.csr \ -CA /Users/admin/Documents/sftofluid-mtls-root-ca.pem \ -CAkey /Users/admin/Documents/sftofluid-mtls-private-key-root-ca.key \ -out /Users/admin/Documents/$NAME.crt \ -days {VALIDITY} -sha256 -
Remove the CSR:
rm /Users/admin/Documents/$NAME.csr
Connect via mTLS
After receiving a signed certificate (.crt) from the CA administrator, pairing it with a private key (.private.key) allows connection to the Fluid Topics API via mTLS.
Run the following commands to create an API call to Fluid Topics via mTLS:
-
Run the following command to define the API endpoint:
export API_URL="{https://xxxx-api.fluidtopics.net/api/khub/locales}" -
Run the following command to define the
$API_KEYvariable.export API_KEY="{MY_API_KEY}" -
Run the following command to establish an mTLS connection:
curl $API_URL \ --header "Authorization: Bearer $API_KEY" \ --header "Content-Type: application/json" \ --cert /path/to/certificate.crt \ --key /path/to/private.key
An API key is necessary to connect to the Fluid Topics API.
Example
Below in an example in which the use case is to list all the maps in a Fluid Topics portal using the johndoe.crt certificate, located in /Users/john/Documents. The private key is named johndoe.private.key and is also saved in /Users/john/Documents:
-
Define the endpoint:
export API_URL="https://anyorg-api.fluidtopics.net/api/khub/maps" -
Define the API key variable:
export API_KEY="QAvt9wRiNb4FbJ4xupng0o2T968jnA1t" -
Establish mTLS connection:
curl $API_URL \ --header "Authorization: Bearer $API_KEY" \ --header "Content-Type: application/json" \ --cert /Users/john/Documents/johndoe.crt \ --key /Users/john/Documents/johndoe.private.key