Skip to main content

Row-level Permission

Introduction

Row-level Permission allows you to grant filtered access for your users (aka record-level permission).

For example, you have many sales people that manage different countries, and you want each of them can only see sales data related to their assigned country.

High-level Mechanism

For Holistics to know what row-level access each user has, your users will need to have some distinct attributes associated with their accounts. We’ll then use these attributes as the basis for filtering. For that, Holistics introduces a concept called 'User Attributes'. You can define an attribute at the user level, and assign unique values for each user.

We then define a Permission Rule at the Dataset level, linking this user's attribute to the relevant dataset's field. The permission rule ensures the user attribute is applied as a filter directly to the dataset's model field whenever the dataset executes.

Now, whenever the user views a dashboard or explores a dataset, the permission rule is automatically applied, filtering the data down to whatever the user is allowed to access.

info

Please note that Permission Rules can be only applied to explorers and business users, not admins, and analysts who have access to the dataset's data warehouse.

Implementation

To understand how to set up Row-level Permission, let's walk through a simple example below.

Use Case

You run an international eCommerce company that has multiple stores located in 6 countries: Vietnam, Indonesia, Malaysia, Singapore, Philippines, United States. For each country, you have one regional manager and many merchant managers.

You want to build a reporting system that:

  • The CEO can see any data from all countries.
  • Each country manager should only see data related to their country.

For example, this is what a Malaysia country manager should see (only data in Malaysia):

Compared with the view of the CEO on the same dashboard. S/he can see data from all countries:

1. Setting up User Attributes

We define a user attribute called 'country_access', and set this value to the relevant country managers. So something like:

You can do this by going to "Manage Users" and click on "Attributes" next to your user.

vn_manager.country_access = ['sg'];
us_manager.country_access = ['us'];
my_manager.country_access = ['my'];
apac_manager.country_access = ['sg', 'my'];
ceo.country_access = All;
...

Do note a few things:

  • You can set multiple values for the user attribute, for example we set country access for apac_manager to both Singapore and Malaysia above.
  • Holistics uses allowlist mechanism. So by default a none-set attribute will be considered None. And that user won't be able to see any data for a permission-ruled dataset.
  • For the CEO, we set their country_access value to All.

2. Setting up Permission Rule in Dataset

Navigate to the Dataset you want to setup permission settings, open more_horiz>Permission Settings modal. Click Add permission to create a new permission rule.

Permision Settings

Map Country Code from Data Model Countries to User Attribute country_access.

info

Please note that Permission Rules can be only applied to explorers and business users, not admins, and analysts who have access to the dataset's data warehouse.

3. Making sure that it works as expected

From now on, when users log in to Holistics, data from all dashboards and widgets that are created from this dataset will always be restricted with the value they are allowed to see from the setup above.

To make sure your permission rules work properly, go to "Organization Settings > View and Edit as" under App Settings to test with each account.

Granting access to a group of users

If you have multiple users that you want to grant access to the same country, it's easier to put all of them in the same user group, and set the attribute at the group's level.

For example, in the below, we create groups 'US', 'SG', 'MY' and set their respective country_access values, and then add the relevant users to those groups.

In the user's attribute dialog, instead of setting a specific value, you can simply choose "Inherit from Groups", and the system auto-resolves the list of values from all the groups this user belongs to.

Determining row-level permission dynamically

The above approach works if you have few employees, and don't mind manually set their permission from time to time. If you have hundreds of employees and already have your own mapping of which countries each employee can access in your existing database. There's a better way to do this:

  • Holistics exposes a system attribute called h_email that's set to the Holistics account's email.
  • When setting up Permission Rule, we use link user's email to the mapping table that's maintained in your database.
  • We don't need to set individual attribute for each user

Given the following tables in a dataset, where employees_countries contains the mapping of which countries each employee can have access to.

Table employees {
id integer [pk]
email varchar
}

Table employees_countries {
employee_id integer [ref: > employees.id]
country_code integer [ref: > countries.code]
}

Table countries {
code varchar [pk]
name varchar
}

Table orders {
id integer [pk]
country_code varchar [ref: > countries.code]
amount integer
}

Instead of setting each of your user's attributes, you can skip that step, and set the Dataset's Permission Rule to the following:

employees.email matches <user_attributes>.h_email

Once that is set up, now every time the dataset is viewed, the data will be filtered down exactly to that user only.

FAQ

Do I have to set up Row Level Permission (RLP) for each model in the same dashboard?

No, the Permission Rule is set up 1 time at the dataset level and will be applied to all models belonged that dataset.

After setting it correctly, all the reports created from the dataset that you have set up the permission will function as expected.

How do multiple permission rules apply to your dataset?

Multiple permission rules are combined by AND logic.


Let us know what you think about this document :)