Exploring CyberArk Central Policy Manager's WSChains

If you have downloaded newer CPM plug-ins from the CyberArk Marketplace, you may have noticed that some deviate from the typical TPC or C#-based implementations and instead leverage a new WSChains DLL with an accompanying XML file. From the plug-in descriptions and the XML file content, WSChains is used when communicating with a REST API.

Scouring the CyberArk technical community and official documentation results in practically zero information about WSChains but studying the XML files of the Marketplace plug-ins utilizing it provides a fair amount of information about this extremely powerful and flexible plug-in type.

First look at WSChains

Like the Secure Web App Framework, WSChains is declarative in nature. It consists of two files: an XML file and the WSChains DLL that acts on it and the contents within.

In the XML, there are four top elements:

  • GlobalSettings

  • Requests

  • Fails

  • Chains

GlobalSettings

Of the three plug-ins I looked at, only one had a child GlobalSetting elements in GlobalSettings.

In the Cisco ISE Internal Users via API plug-in, the GlobalSetting element and the comment imply that the Address property of the account is used as the base URL for all the subsequently defined Request elements.

Requests

The Requests section is made up of RequestWrapper child elements with each RequestWrapper element representing an API call that can be made as part of a later-defined chain.

Within each RequestWrapper there is a Request element where the relative URL, HTTP method, headers, and request body can be defined as child elements. Seemingly, the base URL and the relative URL are automatically concatenated to create the full URL.

Account properties -- including those of the linked logon and reconcile accounts -- are available to use inside the elements of the Request element.

The Tenable.io - CPM plug-in shows that the body can contain JSON when inside a json element.

When the HTTP POST request sends form data and not json, the Request element can look like:

<request name="PasswordChange">
    <version>2</version>
    <general>
        <endpoint>/authentication/users/{{username}}</endpoint>
        <method>POST</method>
    </general>
    <header>
        <Content-Type>application/x-www-form-urlencoded</Content-Type>
        <Authorization>Basic {{username}}:{{pmpass}}</Authorization>
    </header>
    <body>
        <text>
          oldpassword={{pmpass}}&amp;password={{pmnewpass}}
        </text>
    </body>
</request>

It is important to remember when sending multiple key-value paris in the body element, that the ampersand must be escaped as &amp;!

Fails

The Fails section is made up of one or more child Fail elements, which are similar to what you would find in a TPC-based plug-in's Process file.

Chains

The Chains section is where it all comes together.

Each CPM operation has its own Chain element consisting of one or more child Link elements. Each Link element has name and request attributes, where the request attribute's value is the name of a Request element to be executed.

Link elements contain child StatusCode elements, each with a value attribute whose value corresponds to a HTTP status code and a next attribute's value that corresponds to the name of a Fail element or a sibling Link element in the same Chain to be executed when the HTTP status code is matched.

In the case that the value for next is END, similar to a Process file, the operation is considered to have been completed successfully.

StatusCode

The StatusCode elements are particularly interesting.

The content returned in a response's body can be parsed and stored as a variable to be used in Request elements, such as in the case where a session token must first be generated and used as part of subsequent requests.

In the case that the next Link depends not just on the HTTP status code returned but also on the content of a response's body, StatusCode elements can have child Parse elements that in turn have child Equals elements. The Equals elements have next attributes that operate the same as they do with StatusCode elements.

Equals elements are also powerful as the Hitachi Administrator Link CS plug-in shows that they can be used to query an asynchronous job's status.

<Equals value="*" incrementcounter="PollJobCounter" maxcounter="{{maxretries}}"  maxcounterreached="FAILStorageOnboardingFailedChange" sleep="{{sleepseconds}}" next="CheckJobIdStatusLink" />

Wrap-up

With an understanding of CPM plug-ins and REST APIs, it is relatively easy to create your own WSChains-based plug-ins using existing plug-ins as references, even without official documentation. However, since it appears to be an internal-use-only framework for CyberArk, it is not suitable for use in a production setting.

Hopefully, CyberArk will choose to support WSChains in the same way they do TPC and the Web App Frameworks, and provide official documentation. WSChains is powerful in its current state and could potentially replace the need for C# or TPC-based plug-ins developed to interact with REST APIs.