Permission System

In Holistics, you can enforce permission control at several levels.

Please also refer to Manage Users page for more information about user roles and groups

Data Sources Permissions#

Administrators can share data sources to specific analysts from the Manage Data Sources page. Note that even if a data source is shared with an analyst, they cannot view or modify database credentials information of that data source. Behind the scene, the database user that they use to is the one specified in the data source itself. Therefore, the analyst can only run queries against the schemas and tables allowed for that database user.

Report/Dashboard Permissions#

You can share reports, dashboards and folders to specific users or groups. Sharing a folder will automatically share all items inside.

Locking Objects#

Analysts can only lock their own objects, while admins can lock every lockable objects. When an object is locked, it can only be edited by its owner or admins.

Currently, lockable objects are:

  • Dashboards
  • Query reports
  • Query templates
  • Shared filters

Filter Permissions#

In large organizations, it is common that different groups or users use the same reports/dashboards, but they should only have access to the data relevant to them. For examples:

  • Users in the Marketing department only need to see marketing data (Customer engagement, Conversion rates...).
  • Users in the Sales department only need to see sales data (Sales lead, Sales won...) only.
  • Users in the Director group can see both marketing and sales data.
  • Users in the Investor group should only see marketing and sales data in the last 6 months.

In Holistics, user/group permissions applied to Text Input, Date and Dropdown filters. To do this, expand the Permissions field when creating or editing a filter, and then add your permission code into the field.

Syntax References#

The form of a common permission syntax:

- if_group: GroupA
then_value: 'valueA'
- if_group: GroupB
then_value: ['valueB', 'valueC']
- if_group: GroupC
ds_id: 25
query: select val from tableC
- else:
then_value: 'valueD'
expression: Group1 union (Group2 intersect Group3)


  • Condition:
    • if_group: Group name
    • if_user: User email
    • else: No value is needed. This applies to anyone who does not belong to its above condition
  • Outcome:
    • then_value: Value manually added. Must be wrapped in quotation marks like this: 'value'
    • then_sql [ds_id, query]: Value extracted through a query. ds_id is the data source id
    • then_date_min: Min date value
    • then_date_max: Max date value
  • Option:
    • expression: Allows more control over permissions filter. This field defaults to Group1 union Group2 union Group3, where Group1, Group2 and Group3 are added in as in_group. This field could be customized to: Group1 union (Group2 intersect Group3)

Note: Please refer to Filter Permission Syntax (Legacy) if you need to use the old syntax version.


  • Each permission must contain at least one Condition and one Outcome
  • Values after then_value must be wrapped in quotation marks.
  • expression is usable only in Dropdown Filter
  • then_date_min, then_date_max are usable only in Date Filter
  • else syntax can only be used for filters that return a single value

Filter Permission Use Cases#

Restricting Dropdown Filter#

Consider a multi-national organization where employees are based in Singapore, Malaysia, Vietnam etc... with headquarter in Malaysia. We would want to have these permissions:

  • Users in Malaysia can view data from all countries
  • Users in branch countries can only view data from their countries

Here is the sample code for your Country filter:

- if_group: Malaysia
then_value: [my, vn, sg]
- if_group: Vietnam
then_value: vn
- if_group: Singapore
then_value: sg

Then add the Country filter to your SQL query:

WHERE [[ country IN ({{countries}}) ]]

Our permission syntax allows even more complex use cases. For example, in a merchant report, you want to make sure a business user in a country can only see merchants from their own country. However, as your business grows, the list of merchants constantly changes.

Assume that we have connected different data sources containing separated merchant lists for different countries. (For example, Malaysia's data source ID is 101, Singapore is 201, Vietnam is 301...). You can find your data sources' IDs in Data Sources.

Here is a sample code to implement said restriction on your Merchants filter:

- if_group: Singapore
ds_id: 201
query: SELECT DISTINCT id from merchants
- if_group: Vietnam
ds_id: 301
query: SELECT DISTINCT id from merchants

This will map the merchant ID from the country database to the current database. Then add the Merchants filter to your SQL query:

WHERE [[ merchant_name IN ({{merchants}}) ]]

With this setup, the merchant lists unique to each country will always be up-to-date - No need to manually add merchant IDs every time a new merchant is added to the database!

Dynamic access control with "$"#

Example: Ann has been the admin of Merchant 1 and should only see reports for Merchant 1. Now Ann is assigned to Merchant 2 and should only see reports for Merchant 2.

Previously, when there is a switch in personnel like this, the admin will need to do two things:

  • On their system, assign Ann to Merchant 2 on their system.
  • In Holistics: revoke Ann's access to Report 1, then share Report 2 with her. (assuming there are two similar reports for the two merchants)

However, this is not scalable. A better way is to use one report with Merchant ID filter, then use {{ $ }} variable to restrict the merchant IDs available to each user.

Assume that in the ecommerce's system there are merchants and users tables with the following relationship:

We would want to use this permission syntax:

- if_group: Admin
ds_id: 25
query: select from ecommerce.merchants m join ecommerce.users u on m.admin_id = where = {{ $ }}

And the filter query is:

id, name
from ecommerce.merchants
order by 2

When Ann logs in Holistics and access the report, her email will be passed to the permission syntax and become something like this:

- if_group: Admin
ds_id: 25
query: select from ecommerce.merchants m join ecommerce.users u on m.admin_id = where = '[email protected]'

The result is that Ann can only select the merchant that she was assigned to:


This feature is only available for Dropdown Filter and Text Filter.

Parent-Child Filters#

If your filters have a parent-child relationship, the permission applied to the child filter will take precedence. For example, if you are only allowed to view data of Mobiles and Tablets categories:

Then even when you can select parent categories others than Electronics, you cannot see any other child categories:

Restricting Text Filter#

You can make your Text filter read-only and have different values for different groups with filter permission. For example:

- if_group: 'Vietnam'
then_value: 'mkt'
- if_group: 'US'
then_value: 'sale'
- if_user: '[email protected]'
then_value: 'mkt'

We limited the available data for each department depending on the group and email. The result would be like this:


Each group can only have one value. If you set multiple values for a group, the first one will be selected.

Restricting Date Filter#

Example: since Singapore site only launches in May, business users from Singapore should not be able to select dates earlier than that.

To do this, apply the following permission syntax to the date filter:

- if_group: Singapore
then_date_min: '2016-05-01'

This will restrict the user's selectable dates:

You can also use then_date_max to restrict the maximum date selectable.


  • Right now, only exact date values are supported (i.e. no text values such as 3 months ago).
  • If the user belongs to multiple groups that are defined in the permissions section, the first matching group will be selected.