Skip to main content

Brinqa Condition Language

This article details the Brinqa Condition Language (BCL), including the differences between Brinqa Query Language (BQL) and BCL, proper BCL syntax, and where and how to use BCL in your Brinqa Platform.

What is BCL?

BCL is the language used to specify conditions when creating or modifying Risk Factors, Service-Level Agreements (SLAs), or any other feature in the Brinqa Platform that requires a condition for an action to run. The condition is used to define a data set and its syntax is similar to the WHERE clause of a BQL query. For example:

  • riskRating = "Critical"

  • status = "Active"

  • dateCreated IN LAST 30 Days

BCL syntax

The general BCL syntax is as follows:

  • attributeName operator "Value"

The attribute must exist in the target data model, the operator can be any of the BQL operators, and you can specify the value placed in double quotes. (Number and Date values do not have to be wrapped in double quotes.) You do not need to include the name of the data model since you can only create conditions within a data model.

For example, if you want to specify a condition for out-of-compliance high and critical vulnerabilities, you can write the following condition on the Vulnerability data model:

complianceStatus = "Out of SLA" AND riskRating IN ["Critical", "High"]

Since the condition is for the Vulnerability data model, you must ensure that both complianceStatus and riskRating are valid attribute names for Vulnerability. Use the Vulnerability data model documentation to verify. If the data model does not contain the attribute names, the condition does not run.

You can use parentheses () in BCL to group conditions and control the evaluation precedence in the condition. For example, let's say you write the following BCL on the Host data model:

(os = "Windows" OR os = "Linux" OR os = "macOS") AND status = "Active"

The above BCL returns all active hosts that are running on either "Windows", "Linux", or "macOS" operating systems. Without the parentheses, the condition may not yield the expected results, because the AND operator has higher precedence than OR. This means the AND condition would be evaluated first, potentially leading to a different set of results.

note

The AND operation is performed before the OR operation, unless dictated otherwise by the use of parentheses. The precedence of the AND operator over the OR operator is a convention that's been adopted in many programming and query languages, and it mirrors the precedence of logical operators in formal logic and set theory.

Here's another example of using parentheses in BCL:

(complianceStatus = "Out of SLA" AND riskRating IN ["Critical", "High"]) OR (os = "Windows" OR os = "Linux" OR os = "macOS")

The above BCL first evaluates the conditions inside each set of parentheses. Inside the first parentheses, it checks if the compliance status is "Out of SLA" and the risk rating is either "Critical" or "High". Inside the second parentheses, it checks if the operating system (os) is either "Windows", "Linux", or "macOS". If either of these two sets of conditions is met, the item is returned by the query.

Assign relationships in BCL

In BQL, you use the relationship keywords to specify relationships, like SOURCED_FROM, OWNS, or SUPPORTS. For example:

Find Person that OWNS Host Where name CONTAINS "Bob"

The Host data model has an attribute, owners, that defines the OWNS relationship on the Person data model.

BCL also supports the use of relationships, but the syntax is different. Rather than using the keywords, you define relationships with . on the Reference type attributes in the target data model. For example, the following condition is equivalent to the BQL query above:

owners.name CONTAINS "Bob"

The requirement is that the attribute must be a Reference type related to another data model. In this case, owners is an attribute (in the Host data model) that references the Person data model.

If you want to traverse multiple relationships, you can chain additional attributes with additional . . Each attribute must be a Reference type and exists in the target data model. For example, if you want to change the previous condition to filter on the owner’s manager instead, you can write the condition as follows:

owners.managers.name CONTAINS "Alice"

managers is an attribute in the Person data model that references the Person data model.

Reference attribute example

There may be occasions where you want to write a condition that uses a specific attribute, but that attribute does not exist in your target data model. In such cases, if there is an appropriate reference attribute, you can use it to navigate from one data model to another, allowing you to refine your search results by accessing attributes across different data models.

For example, let's say you want to write a condition for the Finding data model and a specific attribute, but you are not sure whether that attribute, such as environments, exists for Finding. To check for the attribute, follow these steps:

  1. Navigate to Administration Admin menu > Data > Models.

  2. Search for Finding and click Attributes.

  3. Search for the environments attribute.

As shown in the screenshot below, the environments attribute does not exist on the Finding data model:

Attribute not existing on Finding data model

We can also confirm that attempting to write a condition on the Finding data model and environments attribute does not work:

Environment condition not working for Finding

Since environments does not exist on the Finding data model, you can check to see if there are any reference type attributes called targets that can connect to a data model that may contain environments. To do so, follow these steps:

  1. On the Attributes page of the Finding data model, search for the targets attribute.

  2. In the Type column, you'll see a reference type attribute that contains the name of another data model. In this example, the data model is Asset:

    Targets attribute on Finding data model

  3. Navigate to the Asset data model, click Attributes, and search for the environments attribute.

As shown in the screenshot below, the Asset data model does contain the environments attribute needed for the condition we want to write:

Environments attribute on the Asset data model

To use the reference attribute in the condition, use the . operator to indicate that it's a referenced value and use the attribute name you want to reference. In this example, to call the environments attribute in the Asset data model from Findings, you can use the following condition targets.environments = "name of the environment":

Using . to link Finding and Asset for Environment

Use regular expressions (regex) in BCL

Complex BCLs with multiple conditions require more processing time for parsing and iterating over each condition, which can lead to slower performance. This is where regular expressions (regex) come into play. By using regex with conditions, you can consolidate multiple conditions into a single, smart condition that handles complex pattern matching, often resulting in better performance compared to multiple discrete conditions.

If you are new to regex or want to test and understand regex better, you can use tools like regex101.com to help get you started. regex101.com provides an interactive environment to create, test, and debug regex patterns, ensuring that the regex is valid.

note

BCL supports the Java flavor of regex. You must use the Java 8 regex flavor with the Match function for the most accurate representation.

Recommended regex settings

Regex example

BCL allows you to write extensive and detailed conditions for queries, but sometimes these conditions can become complicated, especially when dealing with a large number of starts with or ends with conditions. Regex offers a way to streamline these queries, making them more concise and potentially faster.

Consider the following BCL condition that is aimed at retrieving hosts from a specific environment based on name prefixes and a domain suffix:

name ends with ".example.com" and name starts with "prefix1" or name starts with "prefix2" or name starts with "prefix3" or name starts with "prefixN"

As the number of prefixes grows, the condition can become difficult to manage. The above condition can be translated into a single regex pattern:

name =~ ^(prefix1|prefix2|prefix3|prefixN)\.example\.com$

Let's breakdown the regex condition:

  • ^: Asserts the start of a string. In this example, the ^ ensures that one of the patterns, ranging from prefix1 to prefixN, must appear at the start of the name field for a match to be successful.

  • |: Acts as the OR operator between different host names. In this example, the | symbol allows for any pattern ranging from prefix1 to prefixN to match.

  • \.: Escapes the dot, as dot is a special character in regex.

  • $: Asserts the end of a line or a string. This ensures that the pattern preceding the $ symbol must be the last part of the field value to qualify as a match. In the example above, the $ indicates that .example.com must conclude the name field to satisfy the condition.

    The following screenshot illustrates how the regex accurately matches the test strings.

    Regex example

tip

To use this regular expression in the Brinqa Platform with BCL, prepend the pattern with name =~. For example, your BCL condition would look like this: name =~ "^(prefix1|prefix2|prefix3)\.example\.com$"

Important

While regex is technically supported in BQL queries, its use is not encouraged. Using regex in BQL can put a strain on the underlying graph database and lead to performance issues.