Authorization

Two-level permission model in DataLens

The DataLens permission system comprises two levels that work together to decide the actions available to the user.

Level One. Global roles in the system

Every system user gets one of the three global roles, which defines their default behavior in the system. The administrator has access to these settings under Service settingsUsers.

  • Admin: This role can do it all: manage users and settings, view and edit any objects in the system.

  • Creator: The main role for analysts. By default, this role can create connections, datasets, and any other objects in the root folder or wherever it has permissions to operate.

  • Viewer/Visitor: Role for consumers of reports. By default, this role can only view the dashboards it has access to. This role cannot create anything.

Level Two. Object access permissions

In DataLens, you can issue separate permissions for any object:

  • Admin: Full permissions for the object and everything inside it, including access management.

  • Editor: Permissions to edit and create objects inside, e.g., in a folder or workbook.

  • Viewer: View-only permissions.

  • Limited Viewer: Limited Viewer role, with no navigation or structure viewing permissions, ideal for embedding.

How it works together

Object-level permissions can extend the global role’s permissions, but only within the given object.

Example

A user with the global Viewer role cannot create anything by default. Let's suppose this user gets the Editor permissions for a particular workbook named Sales reports.

What this user can do now

  • Create and edit dashboards and charts inside the Sales reports workbook.

  • View other objects they have access to in the system.

What this user CANNOT do

  • Create a new workbook named My reports, because their global Viewer role does not allow creating top-level objects.

  • Create a new database connection, because this is a global action that requires the global Creator or Admin role.

This model enables flexible access management by allowing users to create content only within their own "sandboxes" without littering the global space and without excessive permissions.

Use case

A user has the global Viewer role assigned. Now they get the Editor permissions for a workbook named Marketing. Which of the following actions can the user perform?

  • Create a new dashboard in the Marketing workbook.
  • Create a database connection.
  • Create a new workbook named My personal reports.
  • View dashboards in the Sales workbook if there are viewer permissions available.
Find out the answer
  • Create a new dashboard in the Marketing workbook.

    Correct. The Editor permissions for the workbook allows creating and editing objects inside it, extending the global Viewer role.

  • Create a database connection.

    Wrong. Creating connections is a global action that requires the global Creator or Admin role. The user's global Viewer role does not allow this, and the workbook permissions are irrelevant.

  • Create a new workbook named My personal reports.

    Wrong. The user's global Viewer role does not allow creating top-level objects. The Editor permissions only apply inside the Marketing workbook.

  • View dashboards in the Sales workbook if there are viewer permissions available.

    Correct. The user’s primary global role is Viewer, which is enough to to view anything they have access to.

Configuring authentication providers

To set up integration with external systems, provide a JSON file to init.sh using the --auth-providers-config flag.

./init.sh --auth-providers-config ./my-auth-providers.json

For an example of this file's structure, refer to ./help/auth-provider-config.example.json.

LDAP integration demoed using Active Directory

Consider the most common scenario for corporate environments.

In your JSON file, describe how DataLens should find and authenticate users in the LDAP directory.

Here is a configuration snippet example:

{
  "ldap-main": {
    "title": "Corporate login",
    "type": "ldap",
    "params": {
      "host": "ad.mycompany.com",
      "port": 389,
      "bind-dn": "CN=svc-datalens,OU=Service,DC=mycompany,DC=com",
      "bind-pw": "SUPER-SECRET-PASSWORD",
      "user-search-base": "OU=Users,DC=mycompany,DC=com",
      "user-dn-filter": "(&(objectClass=user)(sAMAccountName=%s))",
      "user-name-attr": "sAMAccountName",
      "user-email-attr": "mail"
    }
  }
}

Debugging with ldapsearch

Before applying the configuration, verify its parameters using ldapsearch.

# Make sure the user named testuser can be found
ldapsearch -x -H ldap://ad.mycompany.com -D "CN=svc-datalens,..." -w "SUPER-SECRET-PASSWORD" \
-b "OU=Users,DC=mycompany,DC=com" '(&(objectClass=user)(sAMAccountName=testuser))'

If the command returns the user's data, your parameters are valid and you may apply the configuration.

Integration via OpenID Connect (OIDC)

OIDC is a modern standard used by Keycloak, ADFS, and other IdPs. It is easier to configure than LDAP.

{
  "oidc-main": {
    "type": "oidc",
    "title": "Log in via Keycloak",
    "params": {
      "issuer": "https://keycloak.mycompany.com/realms/master",
      "client_id": "datalens",
      "client_secret": "ANOTHER-SECRET-KEY"
    }
  }
}

issuer is your OIDC provider’s base URL, where DataLens can automatically get all relevant information, such as authorization endpoints, token URLs, etc.

Why UI_APP_ENDPOINT (ingress.domain) is important

When using OIDC or SAML, your authentication provider needs to know where to redirect the user after a successful login. This is exactly the public URL of your DataLens. The system gets it from the ingress.domain parameter in values.yaml.

If ingress.domain does not match the real URL the users use to access DataLens, authorization will not work due to the redirect_uri_mismatch error.

Tip

We recommend clearing cookies when changing the domain for DataLens.

Automatic group synchronization

You can configure DataLens to automatically add a user to specific groups based on the user’s attributes in LDAP. Do this using the idp-sync.js script from the help directory.

This allows for centralized access management via Active Directory groups instead of assigning permissions to individual users in DataLens manually.

For more complex scenarios, use a separate Node.js script that works with the DataLens API. This is an advanced level extending beyond the basic setup.

External IdP synchronization script

About the script

To run the script, you will need Node.js 20 or higher. You need to set up AUTH_PROVIDERS_CONFIG, the authentication service config. We recommend disabling syncUserGroups in AUTH_PROVIDERS_CONFIG for your IdP if you have used this script to set up periodic synchronization.

Current script version:

  • Creates new IdP users.
  • Creates new IdP groups.
  • Updates user membership in IdP groups.
  • Updates group titles.
  • Updates user roles.
  • Updates user profile data.

Example of running the script

node ./idp-sync.js \
    usEndpoint=https://us.domain.org \
    authEndpoint=https://auth.domain.org \
    usMasterToken=usmastertoken \
    authMasterToken=authmastertoken \
    idpSlug=someidpslug \
    idpData=./idp-data.json
  • idpSlug: Slug from the IdP configuration in the authentication service.
  • usEndpoint: United Storage endpoint.
  • authEndpoint: Authentication service endpoint.
  • usMasterToken: US_MASTER_TOKEN, master token for United Storage.
  • authMasterToken: AUTH_MASTER_TOKEN, master token for the authentication service.
  • idpData: Path to IdP data in JSON format.

IdP data from source

Prepare IdP data in JSON format as per the authentication service's AUTH_PROVIDERS_CONFIG:

type JsonData = {
    users: {
        idpUserId: string, // internal ID of user from IdP
        login: string,
        email : string | null,
        firstName: string | null,
        lastName: string | null,
        roles: string[], // datalens.admin, datalens.creator, datalens.visitor
    }[];
    groups: {
        groupId: string, // internal ID of group from IdP
        title: string,
        memberIds: string[], // internal IDs of users from IdP, idpUserId
    }[];
}

Example of idp-data.json for OpenLDAP:

{
  "users": [
    {
      "idpUserId": "id-bob",
      "login": "bob",
      "email" : "bob@example.org",
      "firstName": "Bob",
      "lastName": "Smith",
      "roles": ["datalens.visitor"]
    },
    {
      "idpUserId": "id-carl",
      "login": "carl",
      "email" : "carl@example.com",
      "firstName": "Carl",
      "lastName": "Snow",
      "roles": ["datalens.creator"]
    }
    ...
  ],
  "groups": [
    {
      "groupId": "id-datalensadmins",
      "title": "DataLens admins",
      "memberIds": ["id-bob", "id-carl"]
    },
    ...
  ]
}

Practical training: Creating a configuration for LDAP

Create a JSON file using fictitious data.

Given:

  • LDAP host: ldap.corp.net
  • Port: 389
  • Bind DN (service account): cn=reader,dc=corp,dc=net
  • Service account password: Read123
  • User search database: ou=people,dc=corp,dc=net
  • Login attribute: uid

Goal: Create the ldap-config.json file with the LDAP provider configuration.

Response
{
  "corporate-ldap": {
    "title": "Employee login",
    "type": "ldap",
    "params": {
      "host": "ldap.corp.net",
      "port": 389,
      "bind-dn": "cn=reader,dc=corp,dc=net",
      "bind-pw": "Read123",
      "user-search-base": "ou=people,dc=corp,dc=net",
      "user-dn-filter": "(&(objectClass=inetOrgPerson)(uid=%s))",
      "user-name-attr": "uid",
      "user-email-attr": "mail"
    }
  }
}

Note: user-dn-filter may differ, but (uid=%s) is the key part.

Summary

You have mastered the demanding admin task of authorization configuration. You can now integrate DataLens with the corporate user directory, understand the difference between roles, and know where to look for potential issues.