Remove sensitive information from data at rest when authenticating to Workspace ONE API's by entering credentials at runtime (part 2)

When it comes to accessing API's and securing your digital workspace, we have options. When accessing Workspace ONE API's, we have options when securely interacting with them; like using base64 encoded credentials, or OAuth access tokens (versions 2001 and newer).

In a previous blog post, we covered how to store sensitive credentials used to access Workspace ONE API's with a config.ini file. This approach works, and while ACL's can limit accounts that can read data at rest; organizations may still prefer to not store credentials in something like json or a old school ini file. 

Today, we'll provide you with your daily dose of uplifting imagery from Hawaii, code to retrieve credentials at runtime, store base64 encoded credentials in memory during execution, and access Workspace ONE API's with the credentials. This way, you can simply hand your code off to operations, sit by the beach, hop on a trail, and enjoy your time in Hawaii.

Waimea Canyon, the Grand Canyon of the Pacific

Maybe you provide your tools to another team to complete a change management event, and the credentials used to access the API's are only valid for a short period of time. We'll help you put a solution together that meets these requirements. So, let's put some data in motion and get to the demo. We'll cover each section of the code to help break down what is happening, and show examples of what to expect.

Line 1-2: Starts with setting PowerShell's verbosity preference. I have become a fan of this, as all write-verbose output is displayed during script execution. I largely discontinue the use of comments in Powershell code, and prefer walking through the code with write-verbose detailing what is happening. Line 2 declares a variable named config and specifies the name of our configuration file, config.ini.

Line 3-49: This is the first function in the code called Test-APICred, where we check if the credential variable is null, and if null, try to get credentials in line 26. The credentials should be in the format of domain\samAccountName (if using LDAP credentials). Any errors are caught on lines 28-33 and 41-46. On line 48, the function Test-APICred is called. Variables instantiated with 'script' in front of the colon have their scope modified to be used throughout. Shoutout to my colleague Aron for getting the phrase instantiated stuck in my head. 😀 
Visual Studio Code, importing a module called DeprovisionApper.psm1 and prompting for credentials

If no credentials are entered, you are continuously prompted to enter credentials

Line 49-50: The variable $UserName has its contents displayed with a write-verbose statement. Line 51 informs me that the code is proceeding to run the second function to create the base64 encoded credentials.

Line 51-62: This is the second function in the code called Set-Base, where we take the contents of the $UserName variable and $Password variable and join them in line 53 with the -join operator. When encoding in to base64, the userid and the password need to be separated by a colon. After joining the userid and password, we finally encode the credentials in line 55. Line 56 checks to see if the variable instantiated is null, and if null; break the script and stop running. After verifying the variable is not null, line 60 informs us that we have the credentials, and we are good to proceed. Line 62 calls the Set-Base64 function.

Line 63-64: Write-verbose statements to inform us during script execution that we are proceeding in the script.

Line 65-92: This is an example of what we can start to do with our base64 encoded credentials. Line 68 sets the $chromeAPPID variable to be null, in the event that the variable is used previously in the script (which it is not). In a prior blog post, we cover how to retrieve data from an ini file, such as the API endpoint URL, API key, etc. Line 67 is where we specify the $appToken variable to be, which is used later on line 79 as a parameter in the request URL sent to the API. Line 68 specifies that TLS 1.2 cipher is required to be used, as per RFC5246, when making the API call. Line 70 and 71 gets the file path where the code is being ran, and then retrieves the contents of an ini file storing environment information called config.ini. Line 71-75 we setup our HTTP Request Header for our API call in line 79. Line 76-89 is where we try to make the API call, and catch any errors when making the call in lines 85-90. Finally we call the function Get-ChromeID in line 92, and identify the unique ID for the Chrome application in line 93. 

Lines 65-92 are simply an example of how to use the base64 encoded credentials when accessing API's. We use the $b64 variable, which contains the credentials, to setup the HTTP Request Header. Once you have instantiated the base64 encoded credentials, you can use them anywhere in the module or script. You could incorporate lines 1-64 in one of the examples I've went over in my blog previously. Other great resources to find code examples VMware's various API's can be found on VMware's GitHub, or VMware's {code} blog.

In this example, sample code has been obtained from Nutanix and PowershellBros.

Ryan Pringnitz


Popular posts from this blog

Zimperium Delivery and Activation on Android Enterprise with Workspace ONE UEM Product Provisioning

Setup Single Sign-On with Workspace ONE & ServiceNow (Mobile Flows Series - Part 1)

Digital Workspace Mobile Threat Detection & Response with Workspace ONE & Zimperium - Integrating zConsole