CompliSpace Role Based Access Control List (RBACL)
This extension provides syntax highlighting for the CompliSpace Role Based Access Control List (RBACL) domain specific language (DSL).
Features

Requirements
There are no special requirements to use this extension.
Extension Settings
There are no extension settings.
Processing User Profiles against RBACL
You can process CompliSpace IdP user objects against RBACL files using the associated npm module: @complispace/idprbacl.
Alternatively, the CompliSpace IdP has two API endpoints that will validate an RBACL and parse a user profile against an RBACL
Validate an RBACL
Sending the RBACL definition to the validate endpoint will result in a set listing the identified roles.
A problem in the definition will result in a 400 response and an object describing the problem.
- Endpoint:
https://idp.complispace.me/api/rbacl/validate
- Method:
POST
Payload
{
"rules": "[CompliSpace Staff]\nACCEPT COMPLISPACE STAFF\nDENY TRUE\n\n[Something Else]\nACCEPT EMAIL ADDRESS IS \"bob.dobbs@example.com\"\nDENY TRUE\n\n[Guest]\nACCEPT NOT AUTHENTICATED\nDENY TRUE\n"
}
Response
{
"roles": [
"CompliSpace Staff",
"Something Else",
"Guest"
]
}
Parse an RBACL
Sending the RBACL definition along with a context to the parse endpoint will result in a map listing the identified roles and if the user has that role.
- Endpoint:
https://idp.complispace.me/api/rbacl/parse
- Method:
POST
Payload
{
"rules": "[CompliSpace Staff]\nACCEPT COMPLISPACE STAFF\nDENY TRUE\n\n[Something Other Role]\nACCEPT EMAIL ADDRESS IS \"bob.dobbs@example.com\"\nDENY TRUE\n\n[Guest]\nACCEPT NOT AUTHENTICATED\nDENY TRUE\n",
"context": {
"user": {
"emails": [
{
"type": "work",
"value": "bob.dobbs@example.com"
}
]
}
}
}
Response
{
"roles": [
[
"CompliSpace Staff",
false
],
[
"Something Other Role",
true
],
[
"Guest",
false
]
]
}
Introduction to the RBACL DSL
Rules
The list of rules is a string where each line is a rules. When given a CompliSpace user object to evaluate, it matches each rule sequentially until a match is made.
Once a match is made the validation returns with the result. If no match is found, then the value undefined is returned. This allows the developer to put explicit rules as the last rule to become the default or take some other action when no matches are made.
A rule consists of a predicate and an assertion.

The predicate determines what is returned by a matching rule, while the assertion is used to make a match.
Predicate
The predicate is one of the keywords ACCEPT or DENY.

The predicate determines the return value when an assertion is matched.
Assertion
An assertion is a boolean test that results as being either TRUE or FALSE.

As you can see from the above railroad diagram, assertions use the standard logic operators (AND, OR, NOT) and can be recursive.
The primitive type for an assertion is a boolean value that is either TRUE or FALSE. All assertions evaluate to a boolean primitive
The derivitave assertions bring an expressiveness to the language that makes it both easy and powerfule to use. For example, ACCEPT AUTHENTICATED. More on defitivie assertions later.
Boolean Assertions
The primitive value of an assertion is a boolean. This can be evaluated by the keywords TRUE and FALSE.
These primitives are useful for testing and illustration purposes.
Putting it Together
That's the minimum required to make an ACL, although it isn't very useful apart from testing.
Let's look at some examples.
Single Line Examples
DENY FALSE
Will evaluate to undefined.
Reason: FALSE means the rule didn't match and because there are no more rules no match succeeded.
DENY TRUE
Will evaluate to false.
Reason: TRUE means the rule matched and since the predicate is DENY the rule returns false.
ACCEPT TRUE
Will evaluate to true.
Reason: TRUE means the rule matched and since the predicate is ACCEPT the rule returns true.
ACCEPT FALSE
Will evaluate to undefined.
Reason: FALSE means the rule didn't match and because there are no more rules no match succeeded.
Multi Line Examples
1. ACCEPT FALSE
2. DENY TRUE
Result: false
The first assertion evaluates to false so the rule is skipped
The second assertion evaluates to true and since the predicate is DENY the result will be false.
1. ACCEPT TRUE
2. DENY TRUE
Result: true
The first assertion evaluates to true and since the predicate is ACCEPT.
The second rule was never parsed since the first rule already evaluated to true.
1. ACCEPT FALSE
2. DENY FALSE
Result: undefined
The assertion in the first rule evaluates to false so it moves on to the next rule.
The assertion in the second rule evaluates to false, but there are no more rules so the result is undefined.
1. ACCEPT AUTHENTICATED
2. DENY TRUE
The assertion in the first rule is checking that the user has been authenticated. If the user has been authenticated then the assertion is true, and since this predicate is ACCEPT the result will be true and no more rules will be processed.
If the user has not been authenticated then processing moves to the second rule. Here the assertion is always true, so with the predicate set to DENY the result will be false.
String Assertions
Strings are values of certain properties such as EMAIL ADDRESS or as literals enclosed by double-quotes such as "bob@example.com".

Comparison between strings can be used in rule assertions. All comparisons are case sensitive.
This is useful when matching various user attributes (more on user attributes later).

EQUALS
lhs EQUALS rhs
Compares two strings for equality. If the value on the left hand side is exactly equal to the value on the right hand side the assertion is true.
"BOB" EQUALS "BOB" will resolve as true
"BOB" EQUALS "BoB" will resolve as false
EMAIL ADDRESS EQUALS "bob@example.com" will resolve as true if the user's email address is bob@example.com and false otherwise.
BEGINS WITH
lhs BEGINS WITH rhs
Checks the string on the left hand side begins with the string on the right hand side evaluating to true if it does and false otherwise.
"Caterpillar" BEGINS WITH "Cat" will resolve as true
"Carpet" BEGINS WITH "car" will resove as false
END WITH
lhs ENDS WITH rhs
Check the string on the left hand side ends with the string on the right hand side evaluating to true if it does and false otherwise.
"Rock Lobster" ENDS WITH "Lobster" will resolve as true
"Pet Shop Boys" ENDS WITH "Shop" will resolve as false
EMAIL ADDRESS ENDS WITH "@example.com" will resolve true if the user's email address ends with @example.com and false otherwise.
CONTAINS
lhs CONTAINS rhs
Check the string on the left hand side contains the string on the right hand side evaluating to true if it does and false otherwise.
"Pet Shop Boys" CONTAINS "Pet" will resolve as true
"Pet Shop Boys" CONTAINS "op B" will resolve as true
"Pet Shop Boys" CONTAINS "Shopping" will resolve as false
NOT
String assertions can be tested for inequality by using the NOT operator in front of the assertion
NOT EMAIL ADDRESS ENDS WITH "@example.com"
NOT DISPLAY NAME EQUALS "Bob Dobbs"
String Functions
Sometimes you don't want to be so strict when comparing strings and case might not matter. In this case there are two function you can wrap around a string to change the case: UPPER and LOWER
UPPER("bob") EQUALS "BOB" will resolve as true
LOWER("BOB") EQUALS LOWER("BoB") will resolve as true

String Lists
Lists of strings can be represented by enclosing them in parenthesis and seperating each item with a comma.

String lists can be represented by the special keywords GROUPS and CN (details on these keywords later).
String List Assertions
String lists can be compared with other string lists and with strings to resolve assertions.

IN
needle IN haystack
Here needle is a string and haystack is a string list. This will resolve true if the element needle exists within the haystack
"bob" IN ("connie", "bob", "dobbs") will resolve as true
NOT IN
needle NOT IN haystack
Here needle is a string and haystack is a string list. This will resolve true if the element needle does not exists within the haystack
"cheese" NOT IN ("rat", "mouse", "budgie") will resolve as true
INTERSECTS WITH
lhs INTERSECTS WITH rhs
With lhs and rhs both being a string list, this operation resolves true if any elements from lhs exists in rhs
("bob", "dobbs", "connie") INTERSECTS WITH ("the", "church", "of", "slack", "bob", "runs") will resolve true
NO INTERSECTION WITH
lhs NO INTERSECTION WITH rhs
With lhs and rhs both being a string list, this operation resolves true if no elements from lhs exists in rhs
("bob", "dobbs", "connie") INTERSECTS WITH ("the", "church", "of", "slack") will resolve true
SUBSET OF
subset SUBSET OF superset
With both subset and superset being a string list, this will resolve true if all elements in the subset exist in the superset
("cat", "dog") SUBSET OF ("budgie", "cat", "dog") will resolve true
("budgie", "cat", "dog") SUBSET OF ("cat", "dog") will resolve false
NOT SUBSET OF
subset NOT SUBSET OF superset
With both subset and superset being a string list, this will resolve true if all elements in the subset do not exist in the superset
("cat", "dog") NOT SUBSET OF ("budgie", "cat", "dog") will resolve false
("budgie", "cat") SUBSET OF ("cat", "dog") will resolve true
String List Functions
Similar to strings, sometimes you don't want to be so strict when comparing string lists and case might not matter. In this case there are two function you can wrap around a string list to change the case: UPPER and LOWER
UPPER("bob", "Dobbs") SUBSET OF ("BOB", "DOBBS") will resolve as true
LOWER("BOB", "dobbs") SUBSET OF LOWER(("BoB", "DObbS")) will resolve as true

User Assertions
User assertions are keywords that resolve various states of the user object.

There is also a 'helper' assertion for testing group membership, however it is expected that non-trivial implementations will use the CN and GROUPS string list attributes as they offer more flexibility.
It is recommended that the use of MEMBER OF be used only if you are after a very specific distinguished name (DN) from a group rather than just the canonical name (CN) part of a group. See CN and GROUPS for more information.

AUTHENTICATED
AUTHENTICATED
Checks if the user has been authenticated. This will resolve true if the user has been authenticated and false otherwise.
Example:
ACCEPT AUTHENTICATED
DENY TRUE
This ACL could be used on a route that can only be accessed by an authetnicated user.
As an interest piece, if the ACCEPT and DENY keywords are swapped, the ACL could be used to allow access to a route that only a non-authenticated 'guest' could access.
COMPLISPACE STAFF
COMPLISPACE STAFF
Checks if the user object represents a CompliSpace staff member. It will resolve true if they are a staff member and false otherwise
Example:
ACCEPT COMPLISPACE STAFF
DENY TRUE
This ACL could be used on a route that is only used by CompliSpace staff. The first rule will resolve true if they are a staff member and false otherwise.
MEMBER OF
MEMBER OF string
If the user is a member of the group string then the assertion will resolve true. Note that the group string will be matched exactly, including case, against a group the user belongs to.
ACCEPT MEMBER OF "administrators"
ACCEPT MEMBER OF "CN=Administrators,OU=MyApp,OU=CompliSpace,OU=Vender,DC=example,DC=com"
DENY TRUE
The first rule will resolve and return true if the user has a group with the name exactly set to "administrators". If they are a member of "Administrators" the assertion will resolve false
The second rule will resolve and return true if the user has a group with the exact name of "CN=Administrators,OU=MyApp,OU=CompliSpace,OU=Vender,DC=example,DC=com".
The third rule resolve to false denying access to the user.
User List Properties
A validated user has a property that is a list of groups the user belongs to. The groups are usualy in the distinguished name (DN) format.
These groups are exposed to the assertion rules as a string list through either the CN or GROUPS keywords

CN
CN
Groups are represented as a distinguished name (DN) but in most cases an application is only interested in the canonical name (CN). The CN can be thought of as the main name of the group.
The CN keyword presents itself as a string list of just the CN value.
For example, consider a user belonging to the groups:
CN=Public RO,OU=Fundamentals,OU=CompliSpace,OU=Vender,DC=example,DC=com
CN=Boardroom RW,OU=Fundamentals,OU=CompliSpace,OU=Vender,DC=example,DC=com
Then the CN keyword would return the string list equivalant of:
("Public RO", "Boardroom RW")
An example of using this would be an ACL of:
ACCEPT "Public RO" IN CN
DENY TRUE
This would resolve as true for any user belonging to a group where the CN attribute is "Public RO"
GROUPS
DN
In most cases the CN of a group is enough, however in some cases you may need to be matching on the full DN.
The DN keyword presents itself as a string list of each group that is fully qualified.
Consider a user belonging to the groups:
CN=Public RO,OU=Fundamentals,OU=CompliSpace,OU=Vender,DC=example,DC=com
CN=Boardroom RW,OU=Fundamentals,OU=CompliSpace,OU=Vender,DC=example,DC=com
The GROUPS keyword would return the string list equivalent of:
("CN=Public RO,OU=Fundamentals,OU=CompliSpace,OU=Vender,DC=example,DC=com",
"CN=Boardroom RW,OU=Fundamentals,OU=CompliSpace,OU=Vender,DC=example,DC=com")
User Properties
A validated user has certain user properties exposed that can be used when evaluating an assertion.

FIRST NAME
The user's first name.
Example:
ACCEPT FIRST NAME IS "Bob"
LAST NAME
The user's last name.
Example:
ACCEPT LAST NAME IS "Dobbs"
DISPLAY NAME
The user's display name.
Example:
ACCEPT DISPLAY NAME IS "Bob Dobbs"
EMAIL ADDRESS
The user's email address is always evaluated as lowercase since email addresses are not case sensitive.
Example:
ACCEPT EMAIL ADDRESS IS "bob.dobbs@example.com"
USER ID
The user's ID.
Example:
ACCEPT USER ID IS "78DB1DE2-B431-44F2-A281-7999DC11137C"
OBJECT GUID
The user's ID.
Example:
ACCEPT OBJECT ID IS "S-1-2-4-5675-263565-2449888"
PROVIDER
The type of authentication provider the user has initially come from.
Example:
ACCEPT PROVIDER IN ("saml", "microsoft", "fundamentals", "complispace")
DIRECTORY
The type of directory store the user came from.
Example:
ACCEPT DIRECTORY IN ("fundamentals", "ldap", "samlproxy", "azure")
USER CONTEXT
Detailed context from the user's provider
Example:
ACCEPT USER CONTEXT IS ("saml/samlproxy/C130599B-93FA-4C5B-A9E9-64C8CD46D2F9")
SITE CODE
The site code the user has signed in from.
Example:
ACCEPT SITE CODE IS "9729f8f73066eeba"