Conditions
This documentation is for an as-yet unreleased version of Cerbos. Choose 0.40.0 from the version picker at the top right or navigate to https://docs.cerbos.dev for the latest version. |
A powerful feature of Cerbos policies is the ability to define conditions that are evaluated against the data provided in the request. Conditions are written using the Common Expression Language (CEL).
Cerbos ships with an interactive REPL that can be used to experiment with writing CEL conditions. It can be started by running cerbos repl . See the REPL documentation for more information.
|
Every condition expression must evaluate to a boolean true/false value. A condition block in a policy can contain either a single condition expression, or multiple expressions combined using the all
, any
, or none
operators. These logical operators may be nested.
condition:
match:
all:
of:
- expr: request.resource.attr.status == "PENDING_APPROVAL"
- expr: >
"GB" in request.resource.attr.geographies
Top-level identifiers
Within a condition expression, you have access to several top-level identifiers:
request
-
Data provided in the check or plan request (principal, resource, and auxiliary data).
runtime
-
Additional data computed while evaluating the policy.
variables
-
Variables declared in the
variables
section of the policy. constants
-
Variables declared in the
constants
section of the policy. globals
-
Global variables declared in the policy engine configuration.
There are also single-letter aliases available to allow you to write terser expressions:
P
-
request.principal
R
-
request.resource
V
-
variables
C
-
constants
G
-
globals
request
objectrequest:
principal: (1)
id: alice (2)
roles: (3)
- employee
attr: (4)
geography: GB
resource: (5)
kind: leave_request (6)
id: XX125 (7)
attr: (8)
owner: alice
auxData: (9)
jwt: (10)
iss: acme.corp
1 | The principal whose permissions are being checked. |
2 | ID of the principal. |
3 | Static roles that are assigned to the principal by your identity management system. |
4 | Free-form context data about the principal. |
5 | The resource on which the principal is performing actions. |
6 | Resource kind. |
7 | ID of the resource instance. |
8 | Free-form context data about the resource instance. |
9 | Auxiliary data sources. |
10 | JWT claims. |
runtime
objectruntime:
effectiveDerivedRoles: (1)
- owner
- gb_employee
1 | Derived roles that were assigned to to the principal by Cerbos while evaluating the policy. This is only populated in expressions in resource policies, and only includes derived roles that are referenced in at least one policy rule. |
Expressions and blocks
condition:
match:
expr: P.id.matches("^dev_.*")
all
operator: all expressions must evaluate to true (logical AND)condition:
match:
all:
of:
- expr: R.attr.status == "PENDING_APPROVAL"
- expr: >
"GB" in R.attr.geographies
- expr: P.attr.geography == "GB"
any
operator: only one of the expressions has to evaluate to true (logical OR)condition:
match:
any:
of:
- expr: R.attr.status == "PENDING_APPROVAL"
- expr: >
"GB" in R.attr.geographies
- expr: P.attr.geography == "GB"
none
operator: none of the expressions should evaluate to true (logical negation)condition:
match:
none:
of:
- expr: R.attr.status == "PENDING_APPROVAL"
- expr: >
"GB" in R.attr.geographies
- expr: P.attr.geography == "GB"
condition:
match:
all:
of:
- expr: R.attr.status == "DRAFT"
- any:
of:
- expr: R.attr.dev == true
- expr: R.attr.id.matches("^[98][0-9]+")
- none:
of:
- expr: R.attr.qa == true
- expr: R.attr.canary == true
The above nested block is equivalent to the following:
condition:
match:
expr: >
(R.attr.status == "DRAFT" &&
(R.attr.dev == true || R.attr.id.matches("^[98][0-9]+")) &&
!(R.attr.qa == true || R.attr.canary == true))
Policy variables
To avoid duplication in condition expressions, you can define variables and constants in policies.
Auxiliary data
If you have auxiliary data sources configured, they can be accessed using request.auxData
.
"cerbie" in request.auxData.jwt.aud && request.auxData.jwt.iss == "cerbos"
Operators
CEL has many builtin functions and operators. The fully up-to-date list can be found at https://github.com/google/cel-spec/blob/master/doc/langdef.md#list-of-standard-definitions. |
Operator | Description |
---|---|
|
Logical negation (NOT) |
|
Subtraction/numeric negation |
|
Unequals |
|
Modulo |
|
Logical AND |
|
Logical OR |
|
Multiplication |
|
Addition/concatenation |
|
Division |
|
Less than or equal to |
|
Less than |
|
Equals |
|
Greater than or equal to |
|
Greater than |
|
Membership in lists or maps |
|
Ternary condition (if-then-else) |
Durations
Duration values must be specified in one of the following units. Larger units like days, weeks or years are not supported because of ambiguity around their meaning due to factors such as daylight saving time transitions.
|
...
"resource": {
"kind": "leave_request",
"attr": {
"cooldownPeriod": "3750s",
"lastAccessed": "2021-04-20T10:00:20.021-05:00"
}
}
...
Function | Description | Example |
---|---|---|
|
Convert a string to a duration. The string must contain a valid duration suffixed by one of |
|
|
Get hours from a duration |
|
|
Get milliseconds from a duration |
|
|
Get minutes from a duration |
|
|
Get seconds from a duration |
|
|
Time elapsed since the given timestamp to current time on the server. This is a Cerbos extension to CEL |
|
Hierarchies
The hierarchy functions are Cerbos-specific extensions to CEL. |
...
"principal": {
"id": "john",
"roles": ["employee"],
"attr": {
"scope": "foo.bar.baz.qux",
}
},
"resource": {
"kind": "leave_request",
"attr": {
"scope": "foo.bar",
}
}
...
Function | Description | Example |
---|---|---|
|
Convert a dotted string or a string list to a hierarchy |
|
|
Convert a delimited string representation to a hierarchy |
|
|
Returns true if the first hierarchy shares a common prefix with the second hierarchy |
|
|
Returns the common ancestor hierarchy |
|
|
Mirror function of |
|
|
Returns true if the first hierarchy is a first-level child of the second hierarchy |
|
|
Mirror function of |
|
|
Returns true if one of the hierarchies is a prefix of the other |
|
|
Returns true if both hierarchies share the same parent |
|
|
Returns the number of levels in the hierarchy |
|
|
Access a level in the hierarchy |
|
IP addresses
The IP address functions are Cerbos-specific extensions to CEL. |
...
"principal": {
"id": "elmer_fudd",
"attr": {
"ipv4Address": "192.168.0.10",
"ipv6Address": "2001:0db8:0000:0000:0000:0000:1000:0000"
}
}
...
Function | Description | Example |
---|---|---|
|
Check whether the IP address is in the range defined by the CIDR |
|
Lists and maps
...
"principal": {
"id": "elmer_fudd",
"attr": {
"id": "125",
"teams": ["design", "communications", "product", "commercial"],
"limits": {
"design": 10,
"product": 25
},
"clients": {
"acme": {"active": true},
"bb inc": {"active": true}
}
}
}
...
Operator/Function | Description | Example |
---|---|---|
|
Concatenates lists |
|
|
Index into a list or a map |
|
|
Check whether all elements in a list match the predicate. |
|
|
Returns the distinct elements of a list |
|
|
Produces the set difference of two lists |
|
|
Check whether at least one element matching the predicate exists in a list or map. |
|
|
Check that only one element matching the predicate exists. |
|
|
Filter a list using the predicate. |
|
|
Flattens a list. If an optional depth is provided, the list is flattened to the specified level |
|
|
Checks whether the lists have at least one common element |
|
|
Check whether the given element is contained in the list or map |
|
|
Produces the set intersection of two lists |
|
|
Checks whether the list is a subset of another list |
|
|
Returns a list of integers from 0 to n-1 |
|
|
Transform each element in a list |
|
|
Returns the elements of a list in reverse order |
|
|
Number of elements in a list or map |
|
|
Returns a new sub-list using the indexes provided |
|
|
Sorts a list with comparable elements |
|
|
Sorts a list by a key value, i.e., the order is determined by the result of an expression applied to each element of the list |
|
|
Converts a map or a list into a list value. The output expression determines the contents of the output list. Elements in the list may optionally be filtered |
|
|
Converts a map or a list into a map value. The key remains unchanged and only the value is changed. |
|
|
Converts a map or a list into a map value; however, this transform expects the entry expression be a map literal. Elements in the map may optionally be filtered |
|
Math
Function | Description | Example |
---|---|---|
|
Returns the absolute value of the numeric type provided as input |
|
|
Performs a bitwise-AND operation over two int or uint values |
|
|
Function which accepts a single int or uint and performs a bitwise-NOT ones-complement of the given binary value |
|
|
Performs a bitwise-OR operation over two int or uint values |
|
|
Perform a left shift of bits on the first parameter, by the amount of bits specified in the second parameter. The first parameter is either a uint or an int. The second parameter must be an int |
|
|
Perform a right shift of bits on the first parameter, by the amount of bits specified in the second parameter. The first parameter is either a uint or an int. The second parameter must be an int |
|
|
Performs a bitwise-XOR operation over two int or uint values |
|
|
Compute the ceiling of a double value |
|
|
Compute the floor of a double value |
|
|
Get the greatest valued number present in the arguments |
|
|
Returns true if the value is a finite number |
|
|
Returns true if the input double value is -Inf or +Inf |
|
|
Returns true if the input double value is NaN, false otherwise |
|
|
Get the least valued number present in the arguments |
|
|
Rounds the double value to the nearest whole number with ties rounding away from zero, e.g. 1.5 → 2.0, -1.5 → -2.0 |
|
|
Returns the sign of the numeric type, either -1, 0, 1 |
|
|
Truncates the fractional portion of the double value |
|
Strings
...
"resource": {
"kind": "leave_request",
"attr": {
"id": "125",
"department": "marketing"
}
}
...
Function | Description | Example |
---|---|---|
|
Encode as base64 |
|
|
Decode base64 |
|
|
Get the character at given index |
|
|
Check whether a string contains the given substring |
|
|
Check whether a string has the given suffix |
|
|
Format a string with the given arguments |
|
|
Index of the first occurrence of the given character |
|
|
Index of the last occurrence of the given character |
|
|
Convert ASCII characters to lowercase |
|
|
Check whether a string matches a RE2 regular expression |
|
|
Replace all occurrences of a substring |
|
|
Replace with limits. Limit 0 replaces nothing, -1 replaces all. |
|
|
Get the length of the string |
|
|
Split a string using a delimiter |
|
|
Split a string with limits. Limit 0 returns an empty list, 1 returns a list containing the original string. |
|
|
Check whether a string has the given prefix |
|
|
Selects a substring from the string |
|
|
Remove whitespace from beginning and end |
|
|
Convert ASCII characters to uppercase |
|
Timestamps
...
"resource": {
"kind": "leave_request",
"attr": {
"lastAccessed": "2021-04-20T10:00:20.021-05:00",
"lastUpdateTime": "2021-05-01T13:34:12.024Z",
}
}
...
Function | Description | Example |
---|---|---|
|
Convert an RFC3339 formatted string to a timestamp |
|
|
Get day of month from a timestamp |
|
|
Get day of month from a timestamp. Returns a zero-based value |
|
|
Get day of week from a timestamp. Returns a zero-based value where Sunday is 0 |
|
|
Get day of year from a timestamp. Returns a zero-based value |
|
|
Get full year from a timestamp |
|
|
Get hours from a timestamp |
|
|
Get milliseconds from a timestamp |
|
|
Get minutes from a timestamp |
|
|
Get month from a timestamp. Returns a zero-based value where January is 0 |
|
|
Get seconds from a timestamp |
|
|
Current time on the server. This is a Cerbos extension to CEL |
|
|
Time elapsed since the given timestamp to current time on the server. This is a Cerbos extension to CEL |
|
timestamp(R.attr.lastUpdateTime) - timestamp(R.attr.lastAccessed) > duration("36h")
timestamp(R.attr.lastUpdateTime) + duration("24h") == timestamp("2021-05-02T13:34:12.024Z")