References - Implementing Playbook Apps Layouts
Overview
This document is intended for the technical audience building an integration with the ThreatConnect Platform. This document is most applicable to someone building an On-Demand Enrichment integration and provides specific instructions for implementing the Playbook Apps Layouts functionality.
Follow the steps in this document in the order provided in order to implement this configuration within your integration.
Implementing Playbook Apps Layouts
For Playbook Apps that provide multiple functions, the Playbook Apps Layouts (Layouts) functionality should be used. This allows you to make use of a wizard based on input values in order to specify only the desired inputs and outputs for a given operation.
Configuration Wizard Steps
The following steps are available for the Layouts configuration wizard regarding input configurations:
Action - This step should contain the primary Action and any sub-action when appropriate.
Connection - This step should contain any connection inputs such as credentials, connection strings, and SSL settings.
Configuration - This step should contain the configurations related specifically to the Action chosen.
Advanced - This step should contain any inputs that are not commonly used, but deemed useful.
When a Playbook author drops your app onto the Playbook canvas, they will be presented with a stepped configuration based on these tabs similar to the images below:
Implementation of Layouts
In order to implement Layouts in your App, you must create the file layout.json. This file simply defines the layouts of inputs and the requirements for inputs and outputs to be available. The latest version of this schema for this file is currently available here (if using an older version of TcEx than current, you can refer to the one included in your version of the tcex library). Please see this section for an example of this file.
Layout.json Parameter Definitions
The table below defines the parameters used in the layout.json file:
Node | Required | Definition | Notes |
inputs > [0] > parameters > [0] > name | Yes | The name of the parameter. | This must match the name in the install.json. |
inputs > [0] > parameters > [0] > display | No | The SQLite statement that controls the visibility of this input parameter. | If the statement evaluates to false, the parameter is not shown. |
inputs > [0] > sequence | Yes | The sequence of the wizard page containing the parameters defined in this section. | |
inputs > [0] > title | Yes | The title of the wizard page containing the parameters defined in this section. | |
outputs > [0] > display | Yes | The SQLite statement that controls the visibility of this output parameter. | If the statement evaluates to false, the parameter is not shown. |
outputs > [0] > name | Yes | The name of the parameter. | This must match the name in the install.json. |
Important Notes for Layouts
When naming your input/output parameters, do not use SQLite Keywords as defined here.
The display parameter uses SQLite for validation.
Use a value of “1” to always include a given output.
All parameters for your App must be included in your layout.json.
Your SQLite statements for the visibility of parameters should be strict.
For example, you should evaluate all parameters that would cause an input or output to be displayed.
Hidden variables can still contain values if they were previously set. You should base your logic on at least one always-required parameter’s value for this reason.
When evaluating against a Checkbox UI element, the proper way to evaluate the True state, for example, is like this
<name> = 'true'
.For example, the input
use_alternate_endpoint
would be evaluated withuse_alternate_endpoint = 'true'
.
You must always include an evaluation for your action in your outputs to ensure that the correct outputs are shown.
Implementation Example Scenario
The following is an example of how you might implement Layouts:
Your app defines the following inputs:
API ID (String)
API Secret (String)
Search Term (String)
Action (Dropdown: Scan Host, Host Report)
Scan Type (Dropdown: Full, Limited)
Report Type (Dropdown: Text, HTML, PDF, All)
Your app defines the following outputs:
sl.results.scan_host.status (String)
sl.results.scan_host.threats (StringArray)
sl.results.host_report.pdf (Binary)
sl.results.host_report.text (String)
sl.results.host_report.html (String)
sl.response.json.raw (String)
Using Layouts, you would limit the inputs to only those needed for each action. In this instance, we want to control inputs based on the following parameters:
Action
If “Scan Host”, we want to display the Scan Type input.
If “Host Report”, we want to display the Report Type input.
Additionally, we want to limit the outputs to only those that are relevant to the requested configuration. In this instance, we want to control outputs based on the following parameters:
Scan Type
If “Full”, we want to include sl.results.scan_host.threats and sl.results.scan_host.status.
If “Limited”, we want to include sl.results.scan_host.status.
Report Type
If “Text”, we want to include sl.results.host_report.text.
If “HTML”, we want to include sl.results.host_report.html.
If “PDF”, we want to include sl.results.host_report.pdf.
If “All”, we want to include sl.results.host_report.text, sl.results.host_report.html, and sl.results.host_report.pdf.
Based on the information above, we might choose to perform our layout in this way for our inputs:
Action Step:
Action
Connection Step:
API ID
API Secret
Configuration Step:
Scan Type
Report Type
Search Term
Advanced Step: none
See the next section for the example configuration that is based on this scenario.
Implementation Example Configuration
Based on the example in the previous section, this layout.json configuration can be used:
{
"inputs": [
{
"parameters": [
{
"name": "action"
}
],
"sequence": 1,
"title": "Action"
},
{
"parameters":[
{
"name": "api_id"
},
{
"name": "api_secret"
}
],
"sequence": 2,
"title": "Connection"
},
{
"parameters":[
{
"name": "search_term"
},
{
"display": "action in ('Scan Host')",
"name": "scan_type"
},
{
"display": "action in ('Host Report')",
"name": "report_type"
}
],
"sequence": 3,
"title": "Configuration"
}
],
"outputs": [
{
"display": "action in ('Scan Host') and scan_type in ('Full','Limited')",
"name": "sl.results.scan_host.status"
},
{
"display": "action in ('Scan Host') and scan_type in ('Full')",
"name": "sl.results.scan_host.threats"
},
{
"display": "action in ('Host Report') and report_type in ('PDF','All')",
"name": "sl.results.host_report.pdf"
},
{
"display": "action in ('Host Report') and report_type in ('Text','All')",
"name": "sl.results.host_report.text"
},
{
"display": "action in ('Host Report') and report_type in ('HTML','All')",
"name": "sl.results.host_report.html"
},
{
"display": "1",
"name": "sl.response.json.raw"
}
]
}