Elements TLS v1.2/Two-Way SSL

This article describes the process for doing Two-Way SSL in Element Builder. Two-Way SSL is also sometimes referred to as SSL, Mutual TLS/SSL, Two-Way TLS, or TLS v1.2.

Not sure what that is? If your API says you need to send a signed certificate for each request, there is a chance this article will help. 

For this example, I will be building authentication for ADP WorkforceNow and making a GET request following these steps:

  1. Create a Java KeyStore formatted certificate.
  2. Configure the element to accept our certificate, and finish authentication.
  3. Create an instance.
  4. Validate with a GET call.

At a more granular level:

  1. Gather files needed create a keystore. I have a .pem file and a .key file, but you may instead/also have a .cer file. 
  2. Convert the .pem file to a .P12 (pks12) file
  3. Create the Java KeyStore from the .P12 (pks12) file.
  4. Base64 encode the Java KeyStore (.jks) file. 
  5. Create an element with custom authentication
  6. Add a custom resource and set "API Type" to "On Provision"
  7. Exchange the Basic Auth token with the Bearer token
  8. make a GET Call. 

Step 1: Create a Java KeyStore formatted certificate

You'll need a couple of files to create your certificate. Usually, this is a .cer, .pem, or .key file (or a combination thereof). For the ADP APIs, I have a .pem and a .key file 

  • In the directory with your files (.cer, .pem, .key), run the following command. Make sure to replace the file names with yours!
    • openssl pkcs12 -export -in MyPemFile.pem -inkey myKeyFile.key -certfile myPemFile.pem -out myPKS12OutputFile.p12

    • When prompted, create a password. 
  • Convert the P12 (pks12) file to a .jks file (Java KeyStore formatted certificate)
  • Run the following command to convert the KeyStore, enter passwords when prompted (save this). Make sure to enter your file names!
    • keytool -importkeystore -srckeystore myP12File.p12 -srcstoretype PKCS12 -destkeystore myJKSCert.jksYou should now have a .jks file in the same directory. 

Step 2: Configure the element to accept our certificate, and finish authentication

The ADP element authentication is as follows

  1. Make a POST to the /Token Endpoint (correct; do not authorize for ADP).
    1. Include a Basic HTTP Auth header with ClientID + Client Secret Base64 encoded with a colon between - ClientID:ClientSecret
    2. Include the certificate on the request.
  2. Set the returned Access_Token body parameter as the Authorization Bearer Token for ongoing requests.
  • Create an element with custom authentication 
  • In Setup>Configuration, select "ADD CONFIGURATION" and select "SSL". This should add two configuration items to our element (Base64.encoded.jks and jks.password
  • Next, we'll need to add configuration for our ClientID, ClientSecret, and Access Token. You may choose to put default values for these for testing, although note that for a production-ready element, they will need to be parameterized. 
    • Add a Global-Pre-Hook setting your Oauth Token to be sent in the Headers on a request
      • let Authorization = `Bearer ${configuration['oauth.token']}`;
        done({'request_vendor_headers': {Authorization}})
  • Now that we've set up our configuration, we need to add an authentication resource and a bit of Javascript to make everything work. 
  • On Resources tab, Add a new resource (POST in ADP's case). This API should reflect the first call made to the vendor during authentication. Since we chose Custom, it's up to the developer to define how/what to call to retrieve the access token. 
    • Set the "Resource Type" to "On Provision", which will call this API when we provision an element instance. 
    • Note the vendor requirements from the ADP API documentation:
    • We still need to tell ADP our Grant-Type. To do this modify the Body "Parameter" on the element resource we've created. 
      • (See the finished product for example)
    • Last, add a bit of Pre-Hook Javascript to 1. Set the Basic Auth header on the provisioning request (1st request), and 2. Set the oauth.api.key to the access_token returned in the response.
      • let Authorization = `Basic ${CE.b64(configuration['oauth.api.key'] + ':' + configuration['oauth.api.secret'])}`;
        done({'request_vendor_headers': {Authorization, 'Content-Type': 'application/x-www-form-urlencoded'}})
    • Post-Hook Javascript:
      • if (response_iserror) done(); 
        done({'configuration': {
        'oauth.token': response_body.access_token
    • The Finished Auth Resource

Step 3: Create an instance 

  • To create an instance (in this case, for ADP), enter the following:
    • Base64 JKS (java KeyStore) file 
      • To base64 encode your keystore file, navigate to the directory and run:
      • base64 -i myJKSCert.jks
      • JKS Password set when you created the KeyStore (jks) file
    • ClientID
    • ClientSecret

Step 4: Validate result by making a GET call