Best practices: Create record access policies and rules

Best practices for creating rules and policies that control user access to data.

Writing record access policy (RAP) rules requires technical knowledge; specifically, a good understanding of the Skedulo data model, the GraphQL API, and EQL (the query language used to filter records).

This page provides guidance and considerations for creating record access rules and policies to help ensure that they work as expected. For information about where in the web app to create policies and rules, and the steps to take to create them, see the user guide.

When writing RAP rules, it’s important to note that:

  • Rules do not work in isolation (rules for the same object type are combined, including any rules that may match because of a hasLookup pattern style rule, and rules from other active policies).

  • The rules you write are further modified by RAP to ensure that mandatory lookups are protected. That is, the EQL that you write in the rule may not behave exactly as written in practice.

  • The effect of rules can change based on the user’s roles and permissions.

Grouping rules into policies

Whether you should combine all rules into a single policy or keep each separated into their own policy depends on your organization’s needs. It’s best to organize rules into meaningful policies that make sense for your use case. The feature provides the flexibility for rules to be logically grouped, but independently managed, together in a single policy or across multiple policies as needed.

Append custom rules to a policy created from template

Policy templates may be updated periodically, but the changes will not automatically be applied to policies that you have created from the template’s previous version. To help manage such updates, we recommend that you keep the templated rules unchanged in one policy and add any customizations in a separate policy. This way, you will be able to apply your customizations to new versions of the template by simply disabling the previous version, and it will be easier to track differences between versions.

Changes to templates are communicated to customers in release notes and the template names will indicate any version change.

Excluding a role or permission from a rule

Record access policy rules are applied to all users, except those with specified roles or permissions. This may raise the question: Why can we only exclude by permission or role and not include a rule by permission or role?

The reasoning is that assigning a role or permission to a user should never reduce their access or capabilities. This allows roles and permissions to be combined together in a sensible and predictable way. Because record access policies are used to restrict access to data, we only provide the mechanism to exclude eligibility for a rule by role or permission. We don’t allow a rule to be included based on a role or permission as that would mean that when someone is given the role or permission it would actually reduce their access to data.

Whether to exclude a role or a permission from a rule

Whether you choose to exclude based on roles or permissions depends on the use case, but maintainability should be considered when making the choice. Excluding by role may mean that you need to update all of your rules if you add a new role. Excluding by permission may be more future-proof. For example, if you were adding policies for different kinds of resources, you could exclude by a permission that only your schedulers have, such as the “View data records” permission (skedulo.tenant.schedule.view).

You can check if excluding by role or permission is working as expected by querying the GET /authorization/policies/rules/resolved endpoint, which returns all active rules applicable to the current user (based on their roles and permissions).

Performance considerations

It is possible to write rules that work for all users (the Region Isolation policy does this by filtering on user and resource regions), however, having more rules results in more complicated queries, which in turn may negatively affect performance.

For this reason, it might be worth excluding rules that only apply to certain users so that the queries are more efficient. In practice, this would mean having a set of rules for each user group by role (for example, one set of rules for schedulers and one for resources), where the rules are applied to each group by excluding the other. The trade-off between rule complexity and performance needs to be assessed for each use case.

Note that the templated region isolation policy will work out of the box regardless of any roles and permissions.

Testing record access policies

Rule validation

If you try to add an invalid filter to a rule, you will receive an error. If you are adding rules via the UI and need extra information on why your filter is not valid, it may help to inspect the skedulo.error header on the UpdateObject POST request in the browser’s dev tools Network tab.

Simulate RAP via EQL

Record access policies insert additional EQL into data queries, so a good way to get to know and understand how the rules will affect what users will see is to try and simulate the policies. This can be done by performing a query with an EQL filter that behaves like the rule you’re creating.

It’s a good idea to do this as an administrator (or user with the view/modify all data permissions) so you don’t have to disable RAP while testing.

When you have an EQL filter that works, you can translate it into a RAP rule and test it by doing a GraphQL query as the user you’re testing the rule for.

Test a rule without affecting other users

If you want to test a RAP rule in a live environment without affecting other users, you can create a special role for testing RAP. You can then configure the new rule to exclude all other roles. When you log in as a user with only the special role, you can verify that the rule behaves as expected before reconfiguring to apply to users more generally.

Use a separate policy to test a rule in isolation

If you want to quickly test rule changes and toggle between having the rule on/off, you can create a temporary new policy and enable/disable it to test the effects of the rule being on/off.

This works because RAP resolves all rules for active policies and combines them.