Create a Multitenant Environment
This tutorial will guide you through the process of creating a multitenant environment. The multitenant environment allows you to share the same measures, insights, dashboards (so-called “analytical model”) among multiple consumers while keeping their data private (each consumer can access only their data).
For example, your company has multiple clients (tenants) who use your application. You want to build a business analytics experience where all your tenants will use the same measures, insights, and dashboards, but each tenant will see only their own data (the data that is relevant to and is associated with a specific tenant). You can also use a multitenant environment inside the company to present different data to different company departments while the analytical model is the same across the company.
A multitenant environment is implemented through a workspace hierarchy and data filters.
- A workspace hierarchy is a tree structure describing relations between parent workspaces and their child workspaces. A child workspace inherits entities from its parent workspace. Any change in the parent workspace is immediately propagated to the child workspace. At the same time, the child workspace can have its own entities in addition to those inherited from the parent workspace. For more information about the workspace hierarchy, see Build a Workspace Hierarchy.
- Data filters allow you to limit the data available in child workspaces. By setting a data filter, you can define what subset of the data from a parent workspace will be available in its child workspaces. For more information about the data filters, see Set Up Data Filters in Workspaces.
The following picture shows how an insight in a child workspace looks like comparing to the same insight in the parent workspace when the data filter that filters the data in the child workspace by region is applied:
To create a multitenant hierarchy, do the following:
Build a Workspace Hierarchy
You are going to create a simple workspace hierarchy where the demo
workspace is a parent workspace with two child workspaces.
graph LR demo --> DemoChild1 demo --> DemoChild2
For more information about the workspace hierarchy, see Build a Workspace Hierarchy.
Steps:
Create a child workspace called
DemoChild1
under thedemo
workspace.BashPowerShell 7curl http://localhost:3000/api/entities/workspaces \ -H "Content-Type: application/vnd.gooddata.api+json" \ -H "Accept: application/vnd.gooddata.api+json" \ -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \ -X POST \ -d '{ "data": { "attributes": { "name": "DemoChild1" }, "id": "demochild1", "type": "workspace", "relationships": { "parent": { "data": { "id": "demo", "type": "workspace" } } } } }' | jq .
Invoke-RestMethod -Method Post -Uri 'http://localhost:3000/api/entities/workspaces' ` -ContentType 'application/vnd.gooddata.api+json' ` -H @{ 'Accept' = 'application/vnd.gooddata.api+json' 'Authorization' = 'Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz' } ` -Body '{ "data": { "attributes": { "name": "DemoChild1" }, "id": "demochild1", "type": "workspace", "relationships": { "parent": { "data": { "id": "demo", "type": "workspace" } } } } }' | ConvertTo-Json
To confirm that the workspace has been created, the server returns the following response:
{ "data": { "id": "demochild1", "type": "workspace", "attributes": { "name": "DemoChild1" } }, "links": { "self": "http://localhost:3000/api/entities/workspaces/demochild1" } }
Similarly, create a child workspace called
DemoChild2
under thedemo
workspace.Go to the home page and check that the two workspaces,
DemoChild1
andDemoChild2
, have appeared in the list of workspaces.(Optional) Open the
DemoChild1
workspace and check that it contains the dashboard and insight that you have created in thedemo
workspace.
How to Create Multiple Child Workspaces at Once
The procedure described earlier is helpful when you need to create just a few child workspaces, and you can create them one by one. If you need to create many workspaces (for example, dozens or hundreds), you can update the declarative layout describing all your workspaces.
Steps:
Download the complete declarative document, and save it to your machine (
/tmp/ws-layout
is used as an example location in the following code samples):BashPowerShell 7curl http://localhost:3000/api/layout/workspaces \ -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \ | jq > /tmp/ws-layout.json
Invoke-RestMethod -Uri 'http://localhost:3000/api/layout/workspaces' ` -H @{ 'Authorization' = 'Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz' } ` -OutFile $env:TEMP\ws-layout.json
The downloaded document contains the definition of the
demo
workspace with all the objects that it holds, and the definitions of theDemoChild1
andDemoChild2
workspaces, which are empty.Add the definition of another child workspace to the document. To do so, add the following JSON object to the top-level
workspaces
array:{ "id": "demochild3", "model": { "analytics": { "analyticalDashboards": [], "filterContexts": [], "metrics": [], "visualizationObjects": [] }, "ldm": { "datasets": [], "dateInstances": [] } }, "name": "DemoChild3", "parent": { "id": "demo", "type": "workspace" } }
Add as many child workspaces as you need by adding more JSON objects with a different name and ID for each workspace.
Upload the updated declarative document back to the server.
BashPowerShell 7curl http://localhost:3000/api/layout/workspaces \ -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \ -H "Content-Type: application/json" \ -X PUT -d @/tmp/ws-layout.json
Invoke-RestMethod -Method Put -Uri 'http://localhost:3000/api/layout/workspaces' ` -ContentType 'application/json' ` -H @{ 'Authorization' = 'Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz' } ` -InFile $env:TEMP\ws-layout.json
Go to the home page and check that the workspaces that you added have appeared in the list of workspaces.
Set Up Data Filters
You now have the workspace hierarchy where the child workspaces inherit the analytical model from the parent workspace, demo
. They also share the same data source and the data stored in this data source.
You are going to set up a data filter to limit the data available in the child workspaces by region, which is determined by the values of the Region
attribute. When the data filter is applied:
- The
DemoChild1
workspace should be able to access only the data that is related to the Western region. - The
DemoChild2
workspace should not be able to access any region-related data.
For more information about the data filters, see Set Up Data Filters in Workspaces.
Steps:
Create a JSON document that describes the data filter. The column that should be used for filtering the data is
region
(it contains the values of theRegion
attribute).To limit the data in the
DemoChild1
workspace to the Western region, assign theWest
filter value to the workspace.To restrict all the region-related data in the
DemoChild2
workspace, do not assign any filter value to it. Because the definition of data filters is tied to the parent workspace, no data will be available in a child workspace if this workspace does not have a filter value explicitly assigned in the filter definition.
{ "workspaceDataFilters": [ { "id": "region", "title": "Customer Region", "columnName": "region", "dataSourceId": "demo-ds", "workspace": { "id": "demo", "type": "workspace" }, "workspaceDataFilterSettings": [ { "id": "region_west", "title": "Region West", "filterValues": [ "West" ], "workspace": { "id": "demochild1", "type": "workspace" } } ] } ] }
Upload the JSON document to the server.
BashPowerShell 7curl http://localhost:3000/api/layout/workspaceDataFilters \ -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \ -H "Content-Type:application/json" \ -X PUT -d @/tmp/ws-filter.json
Invoke-RestMethod -Method Put -Uri 'http://localhost:3000/api/layout/workspaceDataFilters' ` -ContentType 'application/json' ` -H @{ 'Authorization' = 'Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz' } ` -InFile $env:TEMP\ws-filter.json
The data filter is applied.
With this data filter in place, when opening or creating an insight where the Region
attribute is used, you can expect the following:
- In the
demo
workspace, the insight shows data for all the regions. - In the
DemoChild1
workspace, the insight shows only the data related to the Western region. - In the
DemoChild2
workspace, the insight shows no region-related data (no values from theRegion
attribute are available).