Build embedded dashboards with Cumul.io and Auth0 user management
In a previous blog post we had walked through a number of ways to handle multi-tenancy in Cumul.io. Now in this tutorial we will walk through how to configure your Cumul.io dashboard with multi-tenancy based on user information on login, which we manage with Auth0. Before we dive into the specifics, let me give you some context on what these two platforms are used for;
Cumul.io: SaaS that allows you to create your own data insight and analytics dashboards that you can easily integrate and embed within your own platform.
Auth0: A flexible solution to add authentication and authorisation services to your application. You can connect any application to Auth0 and define how you want your users to log in.
You can either clone this repo and follow the steps exactly, or you could take this as a guide for your own setup. The repository already implements a simple single page web app which has an integrated dashboard that you can run locally. To be able to follow these steps you will need a Cumul.io account (Free trials are available here) and an Auth0 account.
Why set up multi-tenancy on your dashboard?
Multi-tenancy on your dashboard gives you the freedom of deciding who sees what when they visit it. It lets you decide for example what an internal user may see (such as an employee) or what an end user may see.
Assume you have a company which owns various products and you want to see how sales are going for each product. You want to have a dashboard that displays this but you don’t want all employees to see all products, rather the one related to their department. This is only one simple example of why you would want user-based filtering. It is so that you can make sure an end user only gets to see what’s intended for them.
Our aim in this tutorial will be to get our imaginary employees Angelina and Brad to go from seeing this:


To these:


How?
- Create a dashboard
- Associate the dashboard to an Integration
- Create an application and users with Auth0
- Add dashboard to web app
- Create rules in Auth0 for relevant user data to be accessed by our app
- Create the relevant parameters for our dashboard to filter on
- Guide to add extra metadata (Optional)
- Useful Resources
Step 1 – Create a Dashboard
First step, log into your Cumul.io account and create a new dashboard (we’ve named ours “Multi-Tenancy Demo”). In this example we use the “United Widgets Sales” dataset, which you can find at:
DATA → (+) → Demo Data → United Widgets Sales →Import:

We have selected a grouped line chart and have used the Month in Datetime for the X axis, the Amount for the Measure and grouped by Product name to obtain the following:

To place the chart and attach data to it, it is a simple drag and drop. You can find the chart and other options on the left ‘Add items’ tab. You can also drop data into the relevant axes from the Data tab.
Step 2 – Associate Dashboard to an Integration
To use and embed the dashboard we created in the previous step in a web application we need to first create and associate it to an Integration in Cumul.io.
- In your Cumul.io account, go to the Integrations tab and Select ‘New Integration’
- Give your integration a name and select which dashboard(s) will be associated to it. Optionally, give the dashboard a slug once you’ve confirmed the selection (in this example we are using the slug ‘multitenancydemo’)

- Select and define the access rights for the datasets this dashboard has access to. In this example we have only used the United Widget Sales dataset

- Once you Create Integration you will see information on how to embed the dashboard, alongside the
integration_id
which we will use later to create an SSO token in our application
Step 3 – Create an Application and Users with Auth0
Let’s assume our company has 2 employees. Angelina Julie and Brad Pots. Now we will add them as users to our app on Auth0.
- In the Applications menu, create a new Application and select Single Page Web Applications:
in Settings:- Copy ‘Domain’ & ‘Client ID’ to the same attributes in the auth_config.json file in the repo you’ve cloned
- In ‘Application URIs’ set the parameters:
Allowed Callback URLs : http://localhost:3000<br>Allowed Logout URLs : http://localhost:3000<br>Allowed Web Origins : http://localhost:3000
- Save Changes
- In the Connections tab, deactivate google-oauth2
- Copy ‘Domain’ & ‘Client ID’ to the same attributes in the auth_config.json file in the repo you’ve cloned
- In the APIs menu, copy the API Audience to the audience attribute in the auth_config.json file.
Here, we use the default System API (Auth0 Management API). But you may also create your own custom API and have the freedom of defining your own permissions:
You can browse permissions in the Auth0 Management API to get an idea of what sort of permissions you would like to include in your custom API.
- Add some users in User Management → Users:
- Go to Users & create 2 users (you will be asked to provide them passwords):
bradpots@exampleapp.com & angelinajulie@exampleapp.com - Now let’s fill in some details about each user. These will be used both as parameters to be used in dashboard filtering later on, and for Cumul.io SSO.
We will fill inuser_metadata
andapp_metadata
for each user.user_metadata
in Auth0 is a field that is editable by users, so we will user this for preferences that they could easily change. We will useapp_metadata
for information that an admin would control and fields that will be used by Cumul.io for SSO.
Generating an SSO token requires ausername
,name
,email
,suborganization
,integration_id
androle
:- In this example we will use
department
as the suborganization while creating an SSO token - You can copy the integration_id from the Integrations tab in Cumul.io
- In this example we will use
- Go to Users & create 2 users (you will be asked to provide them passwords):

//for Brad
{
"user_metadata" : {
"firstName": "Brad",
"language": "fr"
},
"app_metadata" : {
"department": "Quadbase",
"email": "bradpots@exampleapp.com",
"username": "bradpots",
"name" : "Brad Pots",
"integration_id": "*your integration id*",
"role": "viewer",
}
}
//for Angelina
{
"user_metadata" : {
"firstName": "Angelina",
"language": "en"
} ,
"app_metadata" : {
"department": "Linedoncon"
"email": "angelinajulie@exampleapp.com",
"username": "angelinajulie",
"name" : "Angelina Julie",
"integration_id": "*your integration id*",
"role": "viewer",
}
}
Step 4 – Add Dashboard to Web App
If you are following this tutorial with the example repo (cumulio-auth0):
npm install
- Create a file called ‘.env’ in the root directory. Here, create the following 2 keys and add the KEY and TOKEN from your Cumul.io account (You can create one in your Profile settings under API Tokens):
CUMULIO_API_KEY=XXX<br>CUMULIO_API_TOKEN=XXX
- Fill in auth_config.json with your own Auth0 configuration
- In ‘public/js/app.js’ replace
dashboardElement.dashboardSlug = "multitenancydemo";
with your own dashboard’s slug which you can find in the integrations tab(Or, alternatively you could use dashboardElement.dashboardId = “your dashboard Id”)
If you are following this tutorial with your own set up, or would like some more info on how this setup works, we have some additional guidance for you. You can follow the steps in this guide to embed your dashboard within your own setup.
Step 5 – Create Rules in Auth0
This step is where we allow our app to receive metadata for users once they log in. Here, we will use user_metadata for user preferences such as language selection, and we will use fields in app_metadata as parameters for the dashboard to filter on. This will allow users to only see the Sales for only their department.
In order to achieve this, we will add relevant metadata to our jwt tokens. For this, we can add a rule in Auth0:
Go to Auth Pipeline → Rules and create an empty rule with name ‘Add metadata to token’. Here you can use the following code or modify it to your needs. This rule adds the user_metadata and app_metadata to your jwt token.
⚠️ This makes sense for this use case as the user_metadata and app_metadata are both very small here. However if you have large metadata content you may want to consider making a separate call to Auth0 |
function (user, context, callback) {
const namespace = 'https://cumulio/';
user.user_metadata = user.user_metadata || {};
Object.keys(user.user_metadata).forEach((k) => {
context.idToken[namespace + k] = user.user_metadata[k];
context.accessToken[namespace + k] = user.user_metadata[k];
});
Object.keys(user.app_metadata).forEach((k) => {
context.idToken[namespace + k] = user.app_metadata[k];
context.accessToken[namespace + k] = user.app_metadata[k];
});
callback(null, user, context);
}
In server.js, notice the following block of code. This tells Cumul.io that you want to use ‘department’ that you’ve received from the jwt token as a parameter to filter on.
app.get('/authorization', checkJwt, (req, res) => {
const authNamespace = 'https://cumulio/';
client.create('authorization', {
type: "sso",
expiry: "24 hours",
inactivity_interval: "30 minutes",
integration_id: req.user[authNamespace + "integration_id"],
role: req.user[authNamespace + "role"],
name: req.user[authNamespace + "name"],
username: req.user[authNamespace + "username"],
email: req.user[authNamespace + "email"],
suborganization: req.user[authNamespace + "department"],
metadata: {
'department': [req.user[authNamespace + 'department']]
}
})
.then((result) => {
return res
.status(200)
.json({ ssoKey: result.id, ssoToken: result.token });
});
});
In the following section, we will add the parameter to the dashboard and filter the line chart on this parameter.
Step 6 – Create Parameters on the Dashboard
Now the application is receiving department as a parameter, but the dashboard is not doing anything with it. If you run (npm run start), go to localhost:3000 on a browser and log in as Brad, you will still see a chart containing sales data for all departments:

Now it’s time to create a department parameter on the dashboard and add it to a filter:
- On the FILTERS tab on your dashboard, create a parameter called ‘department’ of type Hierarchy[] and add as many department names (from Product Names in the dataset) to this parameter as you want, or even leave it empty (in this case, you will see ‘No Data’ on the Cumul.io admin dashboard once you add the parameter to a filter in the next step).
For more information about how this works and how to set it up, have a look at this article about Parameterizable filters. - Create a filter by going to the FILTERS tab and adding new filter to DASHBOARD FILTERS. You can define your filter as follows:
- Apply
Once you apply this new filter, the chart you see on your Cumul.io dashboard will display data only for product names that are included in the department parameter, and nothing if you haven’t added any values to the parameter.
Now you’re all set! You can run npm run start
and go to localhost:3000
on a browser. Once you login as one of your users you will see that they can only see data related to their department.
For Angelina:

Step 7 – Add Extra Metadata (Optional)
Now that you’ve filtered your dashboard depending on what department your employee works on, let’s walk through what you can do to add something else if you want to. This section is a summary of steps you will need to take, and can be adjusted as you wish.
Assume you don’t only want to filter based on department, but you also want to filter a dashboard based on an employee’s date of employment. For some reason, let’s say you don’t want an employee to see sales data from before they joined. Here’s what you can do:
- Let’s add a ‘join_date’ field to our users’ app_metadata on Auth0. For example:
//for Angelina app_metadata
{
"department": "Linedoncon",
"join_date": "2019-11-01T00:00:00.000Z"
"email": "angelinajulie@exampleapp.com",
"username": "angelinajulie",
"name" : "Angelina Julie",
"integration_id": "*your integration id*",
"role": "viewer",
}
- Add join_date as metadata to send to cumul.io in server.js:
app.get('/authorization', checkJwt, (req, res) => {
const authNamespace = 'https://myexampleapp/';
client.create('authorization', {
type: "sso",
expiry: "24 hours",
inactivity_interval: "30 minutes",
integration_id: req.user[authNamespace + "integration_id"],
role: req.user[authNamespace + "role"],
name: req.user[authNamespace + "name"],
username: req.user[authNamespace + "username"],
email: req.user[authNamespace + "email"],
suborganization: req.user[authNamespace + "department"],
metadata: {
department: [req.user[authNamespace + "department"]],
join_date: [req.user[authNamespace + "join_date"]],
},
})
.then((result) => {
return res
.status(200)
.json({ ssoKey: result.id, ssoToken: result.token });
});
});
- Create a join_date parameter of type Datetime on Cumul.io (We’ve selected 1 September 2017 as default value)
- Add a filter to your dashboard that filters dates greater than join_date and Apply
- Run
npm run start
and go tolocalhost:3000
When you login as Angelina for example, you now only see sales data for dates on and before her join_date (1 Nov 2019)

NOTE: At this point as your code is expecting a join_date field from the metadata it’s receiving from Auth0, you will have to add the same field in other users’ app_metadata.
You are all set and now should have a working web app with an integrated multi-tenant dashboard! Finally, here are some useful resources to conclude:
Some Useful Resources
Cumul.io
- The example repo we use here: cumulio-auth0
- Integration blog and video: How to integrate Dashboards Securely
- Developer documentation: Create an Integration
- Developer documentation: Embed Dashboards
- On Parameters and Filters: Parameterizable Filters
- Webinar on Parameters: How to use parameters