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}}&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 &
!
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.