Understand record access policy rules
Record access policies are groups of filtering rules that apply when accessing data records in Skedulo.
The filters implement row-level security, meaning a user may be able to see some records of a given object type, but not all of them. In database terms, the filter is controlling access to each row of a table, rather than blocking access to the whole table (the object) or a column (a field on the object).
Each policy comprises rules that each define a data access filter for a type of object. The filters limit the data that is returned for any request made by the Skedulo web app, mobile app, or API. A rule always has to be part of a parent policy and rules are enabled and disabled via the parent policy.
For more information about record access policies and how to manage them in the web app, see the user guide.
Important
Policy rules are extremely flexible, but they can also cause the Skedulo web or mobile app to stop functioning properly if configured incorrectly. We recommend that you test new policies and their rules in a separate environment before applying them to your production environment.Record access policy rule fields
Each rule consists of the following fields:
Field | Description |
---|---|
Rule description | A text description that makes it easy to identify the rule’s purpose. |
Object type | The data object that the rule applies to, for example Jobs . This field also supports a hasLookup:<lookup name> value (see Pattern rules below). |
Filter records | The EQL filter that will be applied to the object. See also Rule filters below. |
Access type | Controls how the filter is applied when accessing the object’s data. If set to deny , access will be denied unless it passes the filter condition. This is the normal use case.If set to allow , access will be allowed if the record passes the filter condition. This may be required in special cases.If there are multiple deny filters for the same object, they all need to pass; the conditions are linked with an AND operator.If a deny rule is in effect for an object, an allow rule can be added to conditionally override it; the deny and allow conditions are linked with an OR operator. |
Roles excluded | Users with a role listed in this field will be exempt from the rule. Note that users with the Administrator role, or a role containing the skedulo.tenant.data.viewAll and skedulo.tenant.data.modifyAll permissions, are exempt from all record access policies. |
Permissions excluded | Users with a role that contains any of the permissions in this field will be exempt from the rule. For example, if you have a rule intended for resources, which denies access to jobs unless they are allocated to the current user (resource), you could exclude schedulers from this restriction by adding a permission exclusion for skedulo.tenant.schedule.allocation.dispatch . Schedulers and importantly, any other roles with permission to dispatch, would be able to see jobs regardless of their allocation. |
Rule filters
Record access policy rule filters are defined using Skedulo’s Elastic Query Language (EQL), which is also used in the GraphQL API. See the EQL documentation for more information on how to write and use these filters for the Skedulo data model.
In general, any EQL expression that is valid in a GraphQL request is valid as a RAP rule filter. Note however that referring to a field of a lookup field is not supported in RAP rule filters. A sub-query (IN
clause) must be used instead. For example, for JobAllocations
a GraphQL request would support a filter "Resource.Name != 'secret'"
, but for a RAP rule you would need:
ResourceId IN (SELECT UID FROM Resources WHERE Name != 'secret')
Rule variables
Plain text placeholders resourceId
and userId
are supported in RAP filter expressions. These will be substituted with the relevant values for the user who is making each request. Template variables must be enclosed in double curly braces, for example {{resourceId}}
, {{userId}}
.
Pattern rules
A pattern rule is a rule that applies to multiple object types based on a common pattern in the data model of those objects. The hasLookup:<lookup-name>
pattern can be specified in the object type for a RAP rule in order to match every object type that that has a Lookup field with the given name.
The rule will be applied to all object types in the data model that have defined a lookup with the specified name. For example, to control access to data based an object’s related account (if they have one), you could define a rule with object type hasLookup:Account
.
Note the pattern is based on the name of the lookup relationship in the data model, so the filter can refer to the corresponding ID field (“AccountId” in the above example). If an object had a custom field that was a lookup to the Accounts object but was not named “Account” (say it was “CustomerAccount”), then it would not be affected by this rule.
The names of the lookup relationships in the data model can be found in the GraphL schema for your team or in the Objects and Fields settings in the Skedulo web app.
Record access type
Each rule in a policy has a filter and an access type that determines how the queries work with each other. When there are multiple rules that apply to a given object type, the filters are combined using logic according to the access type. This helps you to separate out complex logic applying to an object type into separate rules that combine to work as a single conditional expression at runtime.
The deny
access type can be thought of as “Deny unless the condition is true”, while the allow
access type can be thought of as “But allow if the condition is true”.
If an object type has a deny
rule in effect but there are cases when the data should be accessible, then you can add an allow
filter that describes when the deny
rule should be overridden.
Another way to think of it is that deny
filters are combined with the AND operator and then allow
filters are added with the OR operator.
Note: Generally, an allow
rule on an object type that does not have a deny
rule has no effect on records of that object type. However, it can still have an impact on another object type because of the filters that are automatically added to handle mandatory lookup relationships. For example, if there was a deny
rule on Regions
, then any job records associated with denied regions would also be denied due to the fact that Jobs has a mandatory lookup to Regions. If an allow
rule is added for Jobs
then the deny
rule on Regions
can be effectively overridden for jobs.
Performance considerations
When creating record access policy rules, be mindful that some rules could have an impact on performance. For example, rules with filters that require searching through the contents of multiple text fields may require considerable computation. As always, rules need to be tested extensively before being put into production to assess their impact on the user experience and data access.
Practical example
Business requirement
Resources must only see jobs that are in their region, but if jobs from other regions have been allocated to them, then they can also see those jobs.
Record access policy solution
This could be achieved by adding two rules for the Jobs
object type; one with access type deny
and one with access type allow
:
- A
deny
rule that only returns jobs in the user’s region:
{
"description": "Deny access to jobs unless they are in a region associated with the user",
"objectType": "Jobs",
"filter": "RegionId IN (SELECT RegionId FROM UserRegions WHERE UserId == '{{userId}}')",
"accessType": "deny",
"rolesExcluded": [],
"permissionsExcluded": [ "skedulo.tenant.schedule.allocation.dispatch" ]
}
- An
allow
rule that returns any jobs that have been allocated to the user, regardless of region (thereby overriding the first rule):
{
"description": "Allow access to jobs that are allocated to the current resource",
"filter": "UID IN (SELECT JobId FROM JobAllocations WHERE ResourceId == '{{resourceId}}' AND Status != 'Deleted' AND Status != 'Declined')",
"objectType": "Jobs",
"accessType": "allow",
"rolesExcluded": [],
"permissionsExcluded": []
}
The Data isolation by region policy rules
Skedulo provides a pre-defined record access policy for “Data isolation by region”. This policy prevents users from seeing any data that is associated with a region unless the user is also associated with that region.
This policy can be seen in more detail in the [Data isolation by region policy template].(/user-guides/admin-and-config/admin-and-config-webapp/permissions-and-data-access-control/use-record-access-policies-to-control-data-access/record-access-policy-templates/#policy-template-data-isolation-by-region).
Rule description | Object | Access type |
---|---|---|
Deny Regions unless they are associated with the user | Regions | deny |
Deny all object types linked to a region, unless its region is associated with the user (pattern rule) | hasLookup:Region | deny |
Deny Activities unless their allocated resource’s region is associated with the user | Activities | deny |
Deny Users unless their region is associated with the user | Users | deny |
Deny Holidays unless they are global or their region is associated with the user | Holidays | deny |
Allow Contacts that do not have a region | Contacts | allow |
Allow Jobs that are allocated to the current resource | Jobs | allow |
Allow Shifts that are allocated to the current resource | Shifts | allow |
To achieve the goal, the policy has a pattern rule of type deny
to only show records that have the same region as the user (as in the example in the previous section).
The policy has additional deny
rules for Holidays
, Activities
, and Users
, because these objects do not have a direct lookup to the Region
object, but are linked via an imtermediate object. For example Holidays
are linked via HolidayRegion
and Users
are linked via UserRegion
.
The policy also has allow
rules so that users can always see work allocated to them, regardless of the region. There is a further allow
rule for Contacts
so that contacts are not hidden when the optional region field is undefined.
Feedback
Was this page helpful?