Operators
When building conditions, you need to be aware of the different types of operators you can use to construct your complex condition rules. There are two types of operators that you need to be aware of - Logical and Comparison.
Logical Operators
There are currently three types of logical operators you need to be aware of. These work like logic gates and represent a boolean function.
Logical Operator | Alias (if any) |
---|---|
AND | allOf |
OR | anyOf |
NOT | not |
Comparison Operators
Comparison operators enable us to construct much more complex conditions and introduce more concrete rules to our policies.
Text | String used in condition | Description | Valid for type |
---|---|---|---|
EQUALS | equals | a = b | Bool, Number, String |
DOES NOT EQUAL | not-equals | a != b | Bool, Number, String |
LESS THAN | less-than | a < b | Number |
GREATER THAN | greater-than | a > b | Number |
LESS THAN EQUALS | less-than-equals | a ≤ b | Number |
GREATER THAN EQUALS | greater-than-equals | a ≥ b | Number |
CONTAINS | contains | "aaa??bbbbbb" | String |
ARRAY CONTAINS | array_contains | ["a", "b", "c"] has "a" | Array |
ARRAY SUBSET | array_subset | ["a", "b"] has ["a", "b", "c"] | Array |
ARRAY SUPERSET | array_superset | ["a", "b", "c"] has ["a", "b"] | Array |
ARRAY INTERSECT | array_intersect | ["a", "b", "c"] and ["c", "d", "e"] share at least one value | Array |
EQUALS REF (reference) | equals-ref | E.G. equals user email | Number, Array, String |
NOT EQUAL REF (reference) | not-equals-ref | E.G. not equals user key | Number, Array, String |
CONTAINS REF (reference) | contains-ref | E.G. tenant name contains user first_name | String |
ARRAY CONTAINS REF (reference) | array-contains-ref | ["admin", "editor"] contains user role | Array |
LESS THAN (reference) | less-than-ref | a < b | Reference to number value E.G user.age |
GREATER THAN (reference) | greater-than-ref | a > b | Reference to number value E.G user.age |
LESS THAN EQUALS (reference) | less-than-equals-ref | a ≤ b | Reference to number value E.G user.age |
GREATER THAN EQUALS (reference) | greater-than-equals-ref | a ≥ b | Reference to number value E.G user.age |
Object Match Operators
Object-match operators enables us to run multiple comparisons on object-like (or dictionary-like) attributes, as well as object-array attributes.
Matching a single Object-typed attribute
Assuming you have a user attribute called user.organization
with type Object
:
{
"name": "Cool Inc",
"country": "US"
"subscription": "pro",
...
}
And you want to have a condition set that filters all users who are working in companies located in the US and have "pro" subscriptions:
If we map each attribute from our source data into a separate attribute in Permit, the conditions would look like this:
{
"allOf": [
{"user.country": {"equals": "US"}},
{"user.subscription": {"equals": "pro"}}
]
}
In other words, normal comparison operators will do the trick.
However with object-typed attributes, we can have a single user.organization
attribute:
{
"allOf": [
{
"user.organization": {
"object_match": {
"match": {
"country": {"equals": "US"},
"subscription": {"equals": "pro"}
}
}
}
}
]
}
As you can see, when you match an object you can use comparison operators within the match
object, for each object-attributes and only if all the conditions match - the operator will return a true
result.
This is beneficial in case you want to map your data as closely to the source data format in your db, but it becomes crucial if you data is an array of dictionaries (or object-array).
Matching Object Array typed attribute
Assuming you have a user attribute called user.organizations
with type Object Array
:
[
{
"name": "Cool Inc",
"country": "US"
"subscription": "pro",
...
},
{
"name": "Awesome Inc",
"country": "IN"
"subscription": "enterprise",
...
},
{
"name": "Sweet Inc",
"country": "US"
"subscription": "enterprise",
...
},
]
In other words, a user can belong to multiple companies, and you still wish to have a condition set that filters all users who are working in companies located in the US and have "pro" subscriptions.
In this case, it is not possible to split the user.organizations
attribute, instead we can match each item of the array:
{
"allOf": [
{
"user.organizations": {
"any_match": {
"match": {
"country": {"equals": "US"},
"subscription": {"equals": "pro"}
}
}
}
}
]
}
This will return true if a single item in the user.organizations
array is an object where item.country == "US"
and item.subscription == "pro"
.
Finally if we want to check if all items in the array match a certain condition we can replace any_match
with all_match
:
{
"allOf": [
{
"user.organizations": {
"all_match": {
"match": {
"country": {"equals": "US"},
"subscription": {"equals": "pro"}
}
}
}
}
]
}
Object Match Operator Reference
Text | String used in condition | Description | Valid for type |
---|---|---|---|
Object Match | object_match | apply conditions to multiple sub-attributes of an object-typed attribute and return true if all the conditions are met | Object |
Any Match | any_match | apply conditions to each item of an object-array attribute (use comparison operators on each sub attribute of the item) an return true if all the conditions are met for at least one item in the array | Object Array |
All Match | all_match | apply conditions to each item of an object-array attribute (use comparison operators on each sub attribute of the item) an return true if all the conditions are met for all the items of the array | Object Array |
Now that we have a basic understanding of the language to construct conditions, lets jump into creating Condition Sets.