Blocks
Last updated
Last updated
Blocks (formerly known as actions) are the building blocks of Workflows. Workflows are made up of individual blocks, which are each responsible for a specific task. A Workflow allows you to run a sequence of tasks that can reference contextual data from your workspace.
To learn how to create a Workflow and configure blocks, see the Workflows documentation.
You must have the Edit Workflows
permission to create, update, and delete Workflows.
Cortex offers a searchable library of blocks that can be added to your Workflows.
In addition to the core blocks listed below, you can also add tasks for your third-party integrations. For example, you can add a block that creates a new repository in GitHub, or you can add a block that creates a new incident in ServiceNow.
Cortex provides prebuilt blocks to perform a variety of actions for the following integrations:
See instructions for configuring integration-related blocks in the Workflows documentation under Step 3: Add blocks to your Workflow.
Cortex provides the following core blocks:
Branch
Data transformation
HTTP request
Manual approval
Scaffolder
User input
See instructions for configuring each type of core block in the Workflows documentation under Step 3: Add blocks to your Workflow.
There may be an instance where you want to repeat a task within your Workflow. It is possible to duplicate an existing block.
To duplicate a block:
In Cortex, navigate to the Workflow that contains the block you want to copy.
Click the 3 dots icon on the right side of the block.
In the dropdown menu, click Duplicate block.
If needed, drag and drop the block to reorder it in the Workflow.
If you're using a Workflow as a way to trigger hooks into internal tooling, we recommend validating that the request is actually originating from Cortex using request signing. Signing secrets are added to requests coming from Workflow blocks.
We add the following headers to each request made by Cortex. Use these headers to verify that the request is valid and originated from Cortex:
x-cortex-timestamp
(current timestamp in millis, used to prevent replay attacks)
x-cortex-signature
x-cortex-signature-256
Note x-cortex-signature
uses the SHA1 algorithm and exists for backward compatibility. SHA1 has been cracked and this signature should be considered deprecated. It is highly recommended to use x-cortex-signature-256
, which uses the SHA256 algorithm.
To configure a signing secret:
In Cortex, navigate to Settings > Secrets, then scroll down to the "Request signing secret" section.
Enter a secret into the text field, then click Save secret.
Calculate the signature (an RFC2104 HMAC):
Create a string with the value $timestamp.$requestBody
if the request body is non-null OR $timestamp
if the request body is null.
Calculate an HMAC using the SHA256 algorithm. Use the Secret you provided to Cortex as the key and the string from Step 1 as the payload.
Verify that the x-cortex-signature-256
matches the HMAC calculated in Step 2.
Each Workflow, when run, will build up a state object. This state can be referenced throughout the Workflow and allows blocks to reference both the top-level state (e.g., who initiated a Workflow) and the state of a previous block.
The Workflow state object includes top-level context
and actions
keys:
context
is immutable, set at the beginning, and available to all blocks.
If an entity changes during Workflow execution, those changes will not be represented in context.entity
.
If secrets change during a Workflow, those changes will not be represented in context.entity
.
You can examine the context object via the Run context tab when viewing a Workflow run.
Read more about the context
key below.
actions
is built up as actions execute via blocks.
Each block will have an inputs
and outputs
key, but their format differs based on the block type.
The state object looks similar to the following:
Workflow state object example
context
keyIf the block is being run in the context of a catalog entity, the template context will contain data about the entity:
tag
name
descriptor
(this is the cortex.yaml
, as an object)
These can be accessed under the {{context.entity}}
key, for example {{context.entity.tag}
or {{context.entity.descriptor.info.x-cortex-git.github.repository}}
The context object also has the following keys:
{{context.initiatedAtIso8601Timestamp}}
: The timestamp at which this block was initiated
{{context.initiatedBy}}
: The user object of the initiator
email
: The user's email
name
: The initiator's name
identityMappings
: A mapping of the identities listed below and their corresponding external IDs:
azure_devops
bitbucket
clickup
github
gitlab
jira
microsoft_teams
opsgenie
pagerduty
service_now
slack
{{context.workflowRunId}}
: The Workflow run ID
Example: initiatedBy.identityMappings.azure_devops
with value 1234
.
You can access your configured secrets by tag: {{context.secrets.SECRET_TAG}}
.
Note that Mustache performs HTML escaping by default, so if your configured secret contains a reserved HTML character, use triple braces to use raw content: {{{context.secrets.SECRET_TAG}}}
.
Secret values are redacted in inputs and outputs of the workflow state.
Accessing a secret in the context
object is not supported for Slack blocks.
You can reference a previous block or a workflow state in several ways:
Templated into block schemas via Mustache ({}
)
Accessed directly from JQ actions
Referenced to define "User input" block overrides
Referenced in "Branch" block path expressions using CEL syntax
Assume a Workflow was created where you gather names from an "HTTP request" block, a "data transformation" block parses the array of names, the names are surfaced to users in a "user input" block where they can select a name, then a "branch" block runs a different path based on which name was selected during the previous "user input" block. In one of the branch paths, there is a "Slack" block that sends a templated message based on the output of previous blocks.
The workflow contains the following blocks:
HTTP request block called users
In this example, the block sends a GET request to gather user names from a URL containing sample data.
Data transformation block called names
It contains a JQ query referencing the output of the users
block:
[.actions.users.outputs.body[] | .name]
User input block called pick-name
It contains an override that references the output of the names
block:
actions.names.outputs.result
Branch block called create-services
There are multiple paths in this branch, depending on which name you chose in the previous block. One of the name options is Ervin
, and there is a conditional path called Ervin
within this block that contains the following path expression. It references Ervin
as the output of the pick-names
block:
actions['pick-name'].outputs.name == 'Ervin' && context.entity.descriptor.info['x-cortex-type'] == 'team'
.
The Ervin
path contains a Slack block to send a templated message via Slack, referencing the output of the pick-name
block and referencing the workflow state by including the email address of the user who initiated the workflow:
We created a service for {{actions.pick-name.outputs.name}}. [message from workflow triggered by {{context.initiatedBy.email}}]
When you run the workflow, the following chain of events occurs:
The HTTP request block gathers user names.
In the "Inputs" tab of this block, you can see where the data was pulled from.
In the "Outputs" tab of this block, you can see the list of names under the body.
The data transformation block parses an array of names from the HTTP request block.
In the "Outputs" tab of this block, you can see the list of names.
The Workflow is paused while awaiting user input. The user input block surfaces a name
field where the user can select a name from the list. The names are from the array parsed in the previous block.
The user selects the name Ervin
, and the Workflow continues to the next block.
The branch block runs a path depending on which name you chose in the previous block. In this example, the Ervin
path runs because the CEL expression for that conditional path was configured to run when the pick-name
block's output is Ervin
.
In the "Outputs" tab of this block, you can see the conditions that were checked to verify which path to run.
The Ervin
path contains a Slack block that sends a templated message referencing the output the previous block and the user who initiated the Workflow. The message is sent to the user with the templated references translated:
We created a service for Ervin. [message from workflow triggered by jdoe@example.com]
To learn more about using blocks in a Workflow, see the Workflows documentation.
A copy of the block will be duplicated in place within the Workflow.