Skip to content

Model access control ​

You can restrict which users can see and query a data model by adding an access block to the model's YAML configuration. Models without an access block are visible to everyone in the account. The same access block can also be added to individual properties to hide specific columns.

Set up user parameters ​

Except for email, user parameters come from user groups configured in Supersimple. Set these up before referencing them in model access rules or row-level security:

  1. Open Account Settings → General.
  2. Under User Groups, select New user group and give the group a descriptive name, such as HR or EU sales.
  3. Open Parameters & permissions for the group and add the parameter keys and values you want to use, such as department=hr or region=eu.
  4. Open Members and add the users who should receive those parameters.

A user can belong to multiple groups. When several groups define the same parameter, the user receives all of those values. For example, membership in groups with region=eu and region=us produces both values for region.

Every account user automatically has an email parameter containing their login email, so email-based rules do not require a user group.

TIP

The User Groups section is available to users with the Manage user groups permission. If you cannot see it, ask an account administrator to configure the groups or grant you that permission.

Basic usage ​

Restrict by user parameters ​

Use user_parameters to require that users have specific parameters assigned to them. All specified parameters must match (AND logic). When a specific property has an array of values, the user must match at least one.

yaml
models:
  salaries:
    name: Salaries

    table: hr.salaries

    access:
      user_parameters:
        department: hr
        data_level: sensitive

    properties:
      employee_id:
        name: Employee ID
        type: String
      salary:
        name: Salary
        type: Number

The user must have department=hr and data_level=sensitive to see this model.

Restrict by email ​

Use user_parameters.email to allow only specific users by their email address.

yaml
models:
  exec_dashboard:

    name: Executive Dashboard

    table: reporting.exec_summary

    access:
      user_parameters:
        email:
          - alice@example.com
          - bob@example.com

    properties:
      revenue:
        name: Revenue
        type: Number

Array values for OR matching ​

When a user parameter can have multiple acceptable values, use an array. The user's parameter must match any one of the listed values.

yaml
access:
  user_parameters:
    region:
      - eu
      - us

This grants access to users with region=eu or region=us.

Combining conditions with AND ​

When you specify multiple conditions at the root level of access, the user must satisfy all of them.

yaml
access:
  user_parameters:
    department: hr
    email: alice@example.com

The user must have department=hr and their email must be alice@example.com.

Creating exceptions with any ​

Use the any block when you want to grant access if the user matches at least one of the conditions. This is useful for creating exceptions — for example, allowing a specific user to access a model without assigning them all the required parameters.

yaml
models:
  salaries:
    name: Salaries

    table: hr.salaries

    access:
      any:
        user_parameters:
          department: hr
          email: special-snowflake@example.com

    properties:
      employee_id:
        name: Employee ID
        type: String

The user has department=hr or is special-snowflake@example.com.

Combining AND and OR ​

Root-level conditions and any can be combined. Root-level conditions are AND-ed together, any conditions are OR-ed, and the two groups are AND-ed with each other: (root conditions) AND (any conditions).

yaml
models:
  sensitive_salaries:
    name: Sensitive Salaries
    table: hr.salaries_sensitive
    access:
      user_parameters:
        data_level: sensitive
      any:
        user_parameters:
          department: hr
          email:
            - special-snowflake@example.com
    properties:
      employee_id:
        name: Employee ID
        type: String

The user must have data_level=sensitive and either department=hr or be special-snowflake@example.com.

Derived models ​

Derived models inherit the access block from their base model by default. You can override this by defining access on the derived model — this replaces the base model's access entirely (it does not merge).

yaml
models:
  salaries:
    name: Salaries
    table: hr.salaries
    access:
      user_parameters:
        department: hr
    properties:
      employee_id:
        name: Employee ID
        type: String

  salaries_public:
    name: Salaries (Public)
    base_model: salaries
    access: {}

An empty access: {} makes the derived model visible to everyone, regardless of the base model's restrictions.

Property access ​

To hide individual columns rather than a whole model, add an access block to a property. It supports the same conditions as a model's access block, including any.

yaml
models:
  employees:
    name: Employees

    table: hr.employees

    properties:
      employee_id:
        name: Employee ID
        type: String
      salary:
        name: Salary
        type: Number
        access:
          user_parameters:
            department: hr

Everyone who can see employees can see employee_id. Only users with department=hr can see salary.

A property without an access block is visible to everyone who can see its model. Property access applies on top of model access: a user must satisfy both the model's and the property's conditions to see the property.

When a user does not satisfy a property's access conditions:

  • The property does not appear in the model's properties and is left out of configuration exports
  • The property cannot be selected, filtered, grouped by, or used in formulas
  • Relations joining on the property are not available
  • Derived models and model operations that use the property fail for that user

Reusable access rules ​

When several models or properties share the same conditions, define the rule once under access_rules and reference it by name. Any access key — on a model, a derived model, or a property — accepts a rule name instead of an inline block.

yaml
access_rules:
  hr:
    user_parameters:
      department: hr
  finance:
    user_parameters:
      department: finance
    any:
      user_parameters:
        role: admin

models:
  employees:
    name: Employees

    table: hr.employees

    properties:
      employee_id:
        name: Employee ID
        type: String
      salary:
        name: Salary
        type: Number
        access: finance
      performance_rating:
        name: Performance Rating
        type: Number
        access: hr

  payroll:
    name: Payroll

    table: hr.payroll

    access: finance

    properties:
      payment_id:
        name: Payment ID
        type: String

Referencing a rule behaves exactly as if its conditions were written inline. The import fails if a referenced rule is not defined in access_rules of the same configuration.

Row-level security ​

In addition to controlling which users can see a model, you can filter the data within a model based on user properties. Use the {{user_parameters.<key>}} placeholder in your model's sql definition to inject the current user's property values into the query at runtime.

Basic example ​

yaml
models:
  orders:
    name: Orders

    sql: |-
      SELECT * FROM orders
      WHERE region IN ({{user_parameters.region}})

    properties:
      order_id:
        name: Order ID
        type: String
      region:
        name: Region
        type: String

For a user with the property region set to eu, the query becomes:

sql
SELECT * FROM orders WHERE region IN ('eu')

Multiple values ​

When a user has multiple values for a property (for example, from belonging to multiple user groups), all values are included as a comma-separated list.

For a user with region values eu and us:

sql
SELECT * FROM orders WHERE region IN ('eu', 'us')

Missing properties ​

If the user does not have the referenced property, the placeholder is replaced with NULL. Since IN (NULL) matches no rows in SQL, the query returns no results.

sql
SELECT * FROM orders WHERE region IN (NULL)

Combining with model access control ​

Row-level security and model-level access control work independently. You can use both on the same model — the access block controls who can see the model, while {{user_parameters.*}} controls which rows they see.

yaml
models:
  regional_orders:
    name: Regional Orders

    sql: |-
      SELECT * FROM orders
      WHERE region IN ({{user_parameters.region}})

    access:
      user_parameters:
        department: sales

    properties:
      order_id:
        name: Order ID
        type: String

Only users with department=sales can see this model, and each user only sees orders matching their region property.

What happens when a model is hidden ​

When a user does not satisfy a model's access conditions:

  • The model does not appear in model listings or the explore UI
  • Queries referencing the model as baseModelId fail with insufficient privileges error
  • Relations pointing to the hidden model are not available
  • Metrics based on the hidden model are not visible
  • Derived models that inherit the base model's access are also hidden