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, assertion
s 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 assertion
s evaluate to a boolean primitive
The derivitave assertion
s bring an expressiveness to the language that makes it both easy and powerfule to use. For example, ACCEPT AUTHENTICATED
. More on defitivie assertion
s 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 assertion
s. 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 assertion
s.
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"