Menu Close Get Metabase

Data sandboxing: setting row-level permissions

Nov 13, 2020 by The Metabase Team

Metabase Enterprise Edition’s data sandboxing feature gives us granular control over what data people can access, from entire databases down to specific columns and rows.

“Sandboxing” often refers to creating an isolated environment that’s used to protect or isolate part of a system.

Metabase uses the term sandboxing in a similar way, except in this case the isolated environment refers to a “data environment.” When an admin grants a group sandboxed access to a table, they can only see the rows and columns included in that sandbox.

In this article, we’ll walk through an example of setting up sandboxed access with the Sample Dataset included with Metabase. Data sandboxes can restrict access to both columns and rows. We’ll cover row-level permissions in this article, and follow up with another article that shows how we can restrict access to table columns as well.

Our goal is to make sure a customer, Ms. Brown, is only able to see table rows related to her account.

Before you sandbox

You should back up your Metabase application data.

In addition, you may want to check out our guide to data permissions and collection permissions to get a better sense of how sandboxing fits in with Metabase’s permissions design.

Creating a customer group

Metabase uses groups to organize permissions, so we’ll first need to create a group, which we’ll call Customers.

We can create Groups in the People tab, which you can get to by clicking on the gears icon in the upper right, selecting Admin to bring up the Admin panel, and clicking on the People tab.

<em>Fig. 1.</em> The Groups page after creating our Customer group.
Fig. 1. The Groups page after creating our Customer group.

Creating a user and adding an attribute

Before we can set sandboxed permissions to the Customers group, we’ll need to create our user, Ms. Brown, and add an attribute to her account.

From the Admin panel’s People tab, we’ll click Add Someone. We’ll fill out the names and email fields, and add her to the Customers group.

And here’s the important part for sandboxing: we’ll add an attribute to our new user, Ms. Brown, with a key of user_id and a value of 20.

<em>Fig. 2.</em> Adding Ms. Brown to the Customers group, and giving her an attribute: <strong>user_id</strong>: 20.
Fig. 2. Adding Ms. Brown to the Customers group, and giving her an attribute: user_id: 20.

Note that there’s nothing magical about the user_id key. It’s just a variable. We can add attributes with whatever key-value pairs we want. And what we want is to use a key that corresponds to a column, and a value that corresponds to row values, for the relevant table that we want to sandbox. The idea is that we’ll link this attribute to a column in a table to determine which rows Ms. Brown can view.

For the sake of this walkthrough, we’re setting this attribute up manually, but we can use authentication services (SSO), like SAML to programmatically assign and synchronize attributes to users.

Granting a group sandboxed access

Now that we have our group, and at least one member of that group with an attribute, we’re ready to head over to the data permissions page to grant the Customers group sandboxed access to tables in the Sample Dataset.

To the left of the grid, under Sample Dataset, we’ll click View tables to view the current data permissions of all the tables.

To grant the Customers group sandboxed access to the Orders table, all we need to do is click on the Customers’ data access cell in the Orders table row and select Grant sandboxed access.

<em>Fig. 3.</em> Granting sandboxed access to the Customer group for the Orders table.
Fig. 3. Granting sandboxed access to the Customer group for the Orders table.

The sandboxed modal will ask “How do you want to filter this table for users in this group?” and present two options:

  • Filter by a column in the table.
  • Use a saved question to create a custom view for this table.

We’ll cover using saved questions in another article, as they are an advanced use case. For now, we’ll leave the setting as Filter by a column in the table.

<em>Fig. 4.</em> The <strong>sandboxed modal</strong> .
Fig. 4. The sandboxed modal .

For the Column, we’ll select the User ID column of the Orders table, and we’ll connect that to the user_id attribute from the dropdown menu of attributes we’ve assigned to users.

Metabase will provide us with a summary of the changes we’ve made: “Users in Customers can view rows in the Orders table where User ID field equals user_id.” Let’s save our changes and repeat the process for the People table.

  • Grant sandboxed access to the Customers group for the People table
  • Select the Filter by a column access.
  • Select the ID column of the People table and connect that to the user_id attribute.
  • Review the summary and click save.

Finally, we’ll need to click the Save Changes button to confirm our changes.

Check settings as our user

Now let’s test out our settings to confirm that our customer, Ms. Brown, can only see orders connected to her User ID.

We’ll open our Metabase instance in an incognito browser window and log in as Ms. Brown. When we navigate to the Orders table, Ms. Brown will only see the orders she placed (User ID 20).

<em>Fig. 5.</em> Ms. Brown will only see orders associated with her ID: 20.
Fig. 5. Ms. Brown will only see orders associated with her ID: 20.

Sandboxing applies to aggregate questions as well. Here’s an Admin’s view of a question that groups all orders by category:

<em>Fig. 6.</em> 'Orders, Filtered by category' question when the admin views it.
Fig. 6. 'Orders, Filtered by category' question when the admin views it.

When viewing that same question, Ms. Brown will only see her orders:

<em>Fig. 7.</em> 'Orders, Filtered by category' question when user 20 views it.
Fig. 7. 'Orders, Filtered by category' question when user 20 views it.

By sandboxing the table, we can create a single question or dashboard, and rest assured that people with sandboxed access to that data will only be able to see the data associated with their account.

If we combine sandboxing with full-app embedding, we can embed these dashboards in our application, and use SSO to pass attributes to the embedded Metabase instance, allowing us to provide sandboxed access to the questions and dashboards embedded in our application. To learn more, see How to embed Metabase in your app to deliver multi-tenant, self-service analytics.

Sandboxing limitations

  • Sandboxing only works with SQL databases.
  • A user can only have one sandbox per table, so only add users to a single group with sandboxed access to a table.
  • If a group has SQL querying access to a database, sandboxing cannot prevent people in that group from viewing data in those tables.
  • By extension, if people in that group have access to questions written in SQL, those questions are unaware of the sandboxing access, and will show people in that group all results, not just the results in that group’s sandbox.

Learn more about the limitations of data sandboxing.

Read more

Stay tuned for an article with an advanced sandboxing walkthrough!

In the meantime, check out our documentation on data sandboxing