Computation rule

Computation Rules are expressions that describe operations to apply to dictionary keys. These keys can come from diverse data sources such as a certification request or a user entry. The available operations and their usage are detailed in this part.

Example

Let’s start by an example:

My CSR contains a DNSNAME subject alternate name with the following value:

host.evertrust.fr

I want my final certificate to have 2 SANs, this value and its short name: "host".

In order to do that, in Profile  Certificate Template  Subject Alternate Names , I add a DNSNAME SAN with the following computation rule:

[{{csr.san.dnsname.1}}, Extract({{csr.san.dnsname.1}}, "(.*?)\.", 1)]

This will output, in my final certificate, two SANs with values:

host.evertrust.fr, host

To explain this result, the value "host.evertrust.fr" was retrieved by choosing the first DNSNAME SAN of the CSR: {{csr.san.dnsname.1}}. The function Extract extracted the first catching group from the regex (.*?)\., resulting in the "host" value.

The computation rule language has a lot more possible operations, allowing complex use cases to become reality.

Dictionary keys

Dictionary keys are a way to name the information from the available sources. For instance, for a webra enroll, the available sources are the given csr, the webra enroll form data and the principal information if it is authenticated. The full list of available dictionary keys is available on the dictionary page.

Enrollment

A key can reference a single element or a list of elements. It is separated in three main parts: the source of data (csr, webra enroll data form), the section of the data, and an optional number

For example, the following is a valid key with these 3 parts:

{{csr.subject.cn.1}}

The csr is the data source, the subject.cn the requested information and the 1 is the index. It allows to retrieve the first, common name from the subject, from the CSR.

Without an index, the key is still valid, but it will output all the corresponding values. For example

[[csr.subject.ou]]

This retrieves all the ou from the subject, from the CSR.

When a key is expected to output a single value it should be written as a single dictionary key, and one outputing a list of values as a multi dictionary key, otherwise it will be none.

Basic expressions

Basic string expressions
The following expressions are evaluated as a string or None.

Expression Name Syntax Allowed Values Description Example

Single dictionary key

{{<key>}}

key: a-zA-A-._

This retrieves a key value from the dictionary, none if it does not exist

{{csr.subject.cn.1}}

Number

<number>

number: -\d+

This will output the given number

-4

Literal

"<literal>"

literal: any string

This will output the given literal

"iAmAString"

Null

NULL

NULL

This will output None

NULL

Now

NOW

NOW

This will output the current instant

NOW

Basic list expressions
The following expressions are evaluated as a list of string or None.

Expression Name Syntax Allowed Values Description Example

Multi dictionary key

[[<key>]]

key: a-zA-A-._

This retrieves all values that start with key from the dictionary

[[csr.subject.cn]]

Array

[<simpleExpression>, …​<simpleExpression>]

simpleExpression: any expression that will be evaluated to a single element

This will output a multi expression composed of all inserted simple expressions

["iAmAString", {{csr.san.dnsname.1}}]

Quick reference

Function names are not case sensitive but keys are
Function Name Syntax

Upper

Upper(expression:<expression>)

Lower

Lower(expression:<expression>)

Trim

Trim(expression: <expression>)

Substr

Substr(expression: <expression>, start: <number>)

Substr

Substr(expression: <expression>, start: <number>, end: <number>)

Concat

Concat(expression: <expression>, …​<expression>)

Extract

Extract(expression: <expression>, regex: <literal>)

Extract

Extract(expression: <expression>, regex: <literal>, group: <number>)

Replace

Replace(expression: <expression>, regex: <literal>, replacement: <expression>)

OrElse

OrElse(expression: <expression>, …​<expression>)

Match

Match(expression: <simpleExpression>, regex: <literal>)

DateTimeFormat

DateTimeFormat(expression: <simpleExpression>, format: <literal>)

Get

Get(expression: <multiExpression>, index: <number>)

First

First(expression: <multiExpression>)

Last

Last(expression: <multiExpression>)

Filter

Filter(expression: <multiExpression>, regex: <literal>)

Slice

Slice(expression: <multiExpression>, start: <number>)

Slice

Slice(expression: <multiExpression>, start: <number>, end: <number>)

Any expression functions

Upper

Upper(expression:<expression>)

This outputs the result evaluated from expression with only upper case characters and None if no value was evaluated

Upper("string") => "STRING"
Upper(["string1", "string2"]) => ["STRING1", "STRING2"]

Lower

Lower(expression:<expression>)

This outputs the result evaluated from expression with only lower case characters and None if no value was evaluated

Lower("STRING") => "string"
Lower(["STRING1", "STRING2"]) => ["string1", "string2"]

Trim

Trim(expression:<expression>)

This outputs the trimmed result evaluated from expression and None if no value was evaluated

Trim(" STRING") => "STRING"
Trim(["string1 ", "  string2  "]) => ["string1", "string2"]

Substr

Substr(expression: <expression>, start: <number>)

This outputs the substring from index start to the end of the string evaluated from expression and None if no value was evaluated or the result of substring is empty. start can be negative and it will be computed from end of string.

Substr("STRING", 2) => "TRING"
Substr(["string", "longerString", "s"], -2) => ["ng", "ng", "s"]
Substr("tooShort", 15) => None

Substr

Substr(expression: <expression>, start: <number>, end: <number>)

This outputs the substring from index start to end of the string evaluated from expression and None if no value was evaluated or the result of substring is empty. start and end can be negative and it will be computed from end of string.

Substr("STRING", 2, 4)  => "TRI"
Substr(["string", "longerString", "s"], 2, -2) => ["tri", "ongerStri"]
Substr("tooShort", -2, 4) => None

Concat

Concat(expression: <expression>, ...<expression>)

This outputs the concatenation of evaluated expressions: if they are all simple expression, a string concatenation will take place, otherwise an array with all the values will be evaluated. If the final result is empty, None will be returned.

Concat("start", " middle ", "end") => "start middle end"
Concat(["string1", "string2", "string3"], "string4") => ["string1", "string2", "string3", "string4"]

Extract

Extract(expression: <expression>, regex: <literal>)

This extracts from the evaluated expression string(s) the part that matches the regex

Extract("[email protected]", ".*@") => "abcd@"
Extract(["string1", "string2", "string3"], "\d") => ["1", "2", "3"]

Extract

Extract(expression: <expression>, regex: <literal>, group: <number>)

This extracts from the evaluated expression string(s) the group at index group that matches the regex

Extract("[email protected]", "(.*)@", 1) => "abcd"
Extract(["string1", "string2", "string3"], "(.*)\d", 1) => ["string", "string", "string"]

Replace

Replace(expression: <expression>, regex: <literal>, replacement: <expression>)

This replaces parts of the evaluated expression string(s) that matches the regex with the evaluated replacement. If replacement is None, values will be replaced by an empty string.

Replace("abcdATdomain.com", "AT", "@") => "[email protected]"
Replace(["string1", "string2", "string3"], "\d", CONCAT("This", " was ", " a number")) => ["stringThis was a number", "stringThis was a number", "stringThis was a number"]

OrElse

OrElse(expression: <expression>, ...<expression>)

This outputs the first non None result of the given expressions, or None if they are all None

OrElse({{not.a.value}}, "[email protected]") => "[email protected]"
OrElse([[no.values]], "value") => ["value"]
OrElse([[no.values]], {{not.a.value}}) => None

String functions

The following functions output a string or None.

Match

Match(expression: <simpleExpression>, regex: <literal>)

This outputs the expression if it matches the regex, otherwise None

Match("abcd", "[a-z]+") => "abcd"
Match("abcd", "\d+") => None

DateTimeFormat

DateTimeFormat(expression: <simpleExpression>, format: <literal>)

This outputs the expression formatted as format. If expression is not a date, no formatting takes place. Available formats are:

  • Custom format in Java DateFormatter syntax

  • MILLIS

  • BASIC_ISO_DATE

  • ISO_LOCAL_DATE

  • ISO_OFFSET_DATE

  • ISO_DATE

  • ISO_LOCAL_TIME

  • ISO_OFFSET_TIME

  • ISO_TIME

  • ISO_LOCAL_DATE_TIME

  • ISO_ZONED_DATE_TIME

  • ISO_DATE_TIME

  • ISO_ORDINAL_DATE

  • ISO_WEEK_DATE

  • ISO_INSTANT

  • RFC_1123_DATE_TIME

    DateTimeFormat(NOW, "MILLIS") => "1709290260764"
    DateTimeFormat(NOW, "hh:mm:ss") => "10:54:57"

Get

Get(expression: <multiExpression>, index: <number>)

This outputs the string at index index in the expression list, and None if the index does not exist. The index can be negative to get from the end of the list.

Get(["string1", "string2", "string3", "string4"], -2) => "string3"
Get(["string1", "string2"], 3) => None

First

First(expression: <multiExpression>)

This outputs the first string of the expression list, and None if it does not exist. The index can be negative to get from the end of the list.

First(["string1", "string2", "string3", "string4"]) => "string1"
First([[no.values]]) => None

Last

Last(expression: <multiExpression>)

This outputs the last string of the expression list, and None if it does not exist. The index can be negative to get from the end of the list.

Last(["string1", "string2", "string3", "string4"]) => "string4"
Last([[no.values]]) => None

List of string functions

The following functions output a list of string or None.

Filter

Filter(expression: <multiExpression>, regex: <literal>)

This outputs a list of string from expression that matches the regex, None if none matches

Filter(["string1", "string2", "match"], "[a-z]+") => ["match"]
Filter(["string1", "string2"], "[a-z]+") => None

Slice

Slice(expression: <multiExpression>, start: <number>)

This outputs the slice of the expression list between start index and its end, or None if the slice is invalid. The index can be negative to get from the end of the list.

Slice(["string1", "string2", "string3", "string4"], -2) => ["string3", "string4"]
Slice(["string1", "string2"], 3) => None

Slice

Slice(expression: <multiExpression>, start: <number>, end: <number>)

This outputs the slice of the expression list between start and end index, or None if the slice is invalid. The index can be negative to get from the end of the list.

Slice(["string1", "string2", "string3", "string4"], 1, 3) => ["string1", "string2", "string3"]
Slice(["string1", "string2"], 3) => None