🌙
 

Subscribe to the Taegis™ XDR Documentation RSS Feed at .

Learn more about RSS readers or RSS browser extensions.

Getting Started Using CEL


Common Expression Language (CEL) is a simple expression language used by Secureworks® Taegis™ Automation. CEL provides simple, consistent, and powerful functionality to manipulate data in Connectors, Templates, Playbook triggers, and Playbook inputs. For more information, see the official Google CEL documentation.

Usage

An expression is always supported by using the ${} syntax. The ${} syntax can be omitted, if preferred, when using expressions within a playbook template or trigger filter for convenience. Note that the ${} syntax must be used when authoring connector definitions.

Example:

Expression:
${'Hello World'}

Output:
Hello World

Find further examples at Common Expression Language Examples.

Data Types

CEL is strongly-typed and supports the following data types:

Data Type Description Example
int 64-bit signed integers
uint 64-bit unsigned integers
double 64-bit IEEE floating-point numbers
bool Booleans (true or false)
string Strings of Unicode code points
bytes Byte sequences
list Lists of values [1,2,3]
map Associative arrays with int, uint, bool, or string keys {'key':'value'}
null_type The value null
message names Protocol buffer messages
type Values representing the types in the first column string

In many cases, a data type can be converted using built-in macros: int(), uint(), double(), string(), list(), map(), bool(), bytes(). For example, to convert a number to a string:

Expression:
${ string(8) }

Output:
8

Expression:
${ type(string(8)) }

Output:
string

In most cases, defining the value of a variable also sets the data type:

Expression:
${ {'key':'value'} }

Output:
a map data type, with a single key called "key" and a value of "value"

Expression:
${ [1,2,3] }

Output:
a list data type, with the values 1, 2, and 3

Expression:
${ [] }

Output:
an empty list

Expression:
${ 'this is a string' }

Output:
this is a string

Accessing Data

Data can be accessed by referencing the variable name:

Expression:
${myvar}

Data in a map can be accessed via one of the following methods (the expressions return the same result):

Expression:
${map_var.map_key}

Expression:
${map_var['map_key']}

Output:
the value associated with the key map_key in the map_var map variable

List elements can be accessed if you know the element order (zero-based):

Expression:
${mylist[0]}

Output:
the value of the first element in the mylist list variable

Conditionals

CEL does not support a traditional if, then, else syntax, but it does support a ternary conditional. A ternary is a shortened if, then, else that has the following structure: <if> ? <then> : <else>. Where <if> is any expression that evaluates to a true/false boolean value. <then> can be any expression and will be returned if the condition is true. <else> can be any expression and will be returned if the condition is false. Note that the data type of the <then> and <else> values must match.

Expression:
${ int_val > 3 ? 'int_val is greater than 3' : 'int_val is less than 3' }

Output (int_val=4):
int_val is greater than 3

Output (int_val=2):
int_val is less than 3

Macros

A number of macros are supported which extend the functionality of language. Macros typically only apply to and accept specific data types. For example, the toLower() macro applies to a string or a list.

Expression:
${'Hello World'.toLower()}

Output:
hello world

Expression:
${toLower(['Hello World'])}

Output:
[
  hello world
]

Many of the supported macros are documented at Common Expression Language Macros.

Avoiding Errors

Attempting to access a variable that is not defined will result in a no_such_field error. This can be avoided by using the has() macro along with a ternary conditional:

Expression:
${ has(map_var, 'map_key') ? map_var.map_key : '' }

Output:
the value of map_var.map_key if it exists, else an empty string

Another common error is due to mismatched type values. Converting the data in a variable to a specific data type may be necessary to prevent this issue. For example:

Expression:
${ int(int_val) }

Output:
the value of int_val as an integer type

 

On this page: