Apache Superset row level security

Row level security decides which rows each Superset user, role or group sees in charts and dashboards. This page explains how to plan, configure and test RLS filters before wider rollout.

On this page

Apache Superset row level security: when teams need it and what it changes

A team that shares one analytics database across regions, business units or customers often needs each Superset viewer to see only their own rows, even when they open the same dashboard. Row level security (RLS) is the Superset feature that solves this: it attaches SQL conditions to datasets and roles so that queries generated by charts and dashboards are filtered before results reach the viewer. The Superset documentation describes RLS filters as SQL conditions tied to datasets and to roles, which means the filter logic lives in Superset's metadata, not in the database itself. Deciding to use RLS is therefore a governance decision that should be made before rollout, because it determines which population of users sees which data and who is allowed to change those rules.

RLS does not replace database privileges. A user who connects to the warehouse directly, through SQL Lab, a CSV upload, another BI tool or an unfiltered service account, can still reach rows that a Superset filter would hide. Before writing any filter, confirm which database accounts Superset uses, what those accounts can read, and whether analysts have separate direct access. Also confirm who holds the permissions to create and edit RLS rules, since a person who can change a filter can change what a whole group sees. Your security and data owners should agree on the source of truth for each filter, such as a region or tenant column, and on how that column is protected from users who could modify it.

Expect the effort to sit in the design and testing stages rather than in the clicks needed to create a filter. Each filter needs a defined group or role key, a clear rule for users who match several groups, and a plan for users who match none, which the filter logic must handle explicitly. Ask any partner for a written list of the datasets, roles and filter conditions in scope, the test accounts used to prove each rule, and the change process for editing rules after go-live. Those artifacts, and not the number of filters configured, are what your auditors and business owners will need to review.

Regular filters versus base filters and how they combine

A regular filter is attached to one or more roles and adds a WHERE condition to queries only when the user running the query holds one of those roles. Users in other roles see the same dataset without that condition. Regular filters suit cases where each team, region or business unit should see a distinct slice of one table.

  • Role assignment: Each filter lists the roles it applies to, so the condition is added only for members of those roles.
  • Clause definition: The clause is SQL entered against a specific dataset, such as a column comparison on a region or business unit field.
  • Layered restriction: A regular filter narrows what a role sees within datasets it can already query. It is not a substitute for dataset-level permissions.
  • Team-based slices: A sales table can give each regional role its own filter, which avoids copying the table for each region.

For each regular filter, confirm the listed roles and check with a test user from an unlisted role that the filter does not apply to them.

Group keys and Jinja-driven user filters

A group key lets several RLS filters on the same dataset apply in a controlled way. Superset combines filters that share a group key with OR, and filters with different group keys with AND, so a user who matches any filter in a group sees the rows that group allows, while every group must still be satisfied. Before you assign keys, map the access rules on paper: which roles see which regions, departments or tenants, and whether any rule should narrow access for everyone regardless of role. Then confirm in your Superset version's documentation how group keys and base filters interact, because a misplaced key is the most common way a filter silently widens access. Test each combination with a non-admin account rather than trusting the filter list in the UI.

Jinja expressions let a single filter clause adapt to the person running the query. Clauses can reference the current username or user attributes, for example to match a region column against a value stored on each user's profile. This only works when Jinja templating is enabled for the dataset, and it makes the RLS clause itself dynamic SQL. Because RLS clauses are raw SQL, anyone who can create or edit them can change who sees which rows, so restrict edit rights to a small set of data owners and record every change. The security implications of templating extend beyond RLS, and the Apache Superset Jinja SQL templating topic covers the server-side template injection risk that decides who may edit datasets once templating is on.

Design decisions to make before writing filters

Row level security is only as good as the decisions behind it. The choices below determine which data is filtered, where each user's attributes come from, and what happens when a user matches no rule. Settle them together before anyone writes a filter clause.

Which datasets need row filters

Start with an inventory of datasets that hold data split by customer, region, business unit or classification. Each one needs an owner who decides the filter logic. Datasets that are public within the organization may not need RLS at all, and adding filters to them only increases query complexity. Confirm which tables are shared across dashboards, because a filter attached to one dataset applies to every chart built on it. Note that RLS governs what Superset returns to users, so it does not replace database-level permissions for direct connections.

Source of the user attribute

Decide where the value that drives each filter comes from. Local Superset users carry attributes you maintain by hand. OAuth or LDAP users get roles through AUTH_ROLES_MAPPING, which maps identity provider groups to Superset roles. If the filter relies on a group, confirm that the group is maintained by the system of record and that removing a person from it removes their data access. Stale group membership is the most common source of rows users should no longer see.

Role-based or per-user filters

Decide whether filters attach to roles, so that every member of a group shares one rule, or to individual users. Role-based filters are easier to review and audit because a small set of rules covers many people. Per-user filters are precise but grow with headcount and are harder to test as a set. Many teams combine them, using a role for the broad division and a user-level clause for exceptions. Write down which approach applies to each dataset before creating any filter.

Default-deny or default-allow for unmapped users

Decide what a user sees when no filter matches them, for example an account with no group mapping or a new hire before provisioning finishes. A default-deny design returns no rows to unmapped users, which fails closed but can confuse people during onboarding. A default-allow design shows all rows, which exposes data if a mapping is missing. Test the behavior with an account that has no roles, and confirm the outcome matches the written policy for each sensitive dataset.

How administrators are excluded

Decide whether administrators and data stewards bypass row filters or are subject to them. Admins who see everything can troubleshoot dashboards, but their access must then be governed and logged. Admins who are filtered may be unable to verify what users see, which slows support. Record the answer, the role that carries the exception, and who is allowed to hold it. Review this list on the same schedule as other privileged access reviews.

How to configure and test RLS filters in sequence

This sequence takes a Superset row level security design from a staging check of the metadata database and identity mapping to a recorded set of test results that shows each role sees only its own rows. Work through the steps in order, because later checks depend on the test data and accounts created earlier.

  1. Confirm metadata database and identity mapping

    The platform team confirms that staging runs Superset against a supported metadata database, PostgreSQL or MySQL, and not the SQLite default used by quickstart installs. The security lead then confirms how the identity provider's groups or roles map to Superset roles through the authentication configuration, so every test user lands in the role the RLS rule expects. Check the metadata database version against the configuration documentation and record the group-to-role mapping in writing. This step is done when a test login produces the expected Superset roles in the user profile.

  2. Create the test dataset and test users

    The data owner creates a small test table in a staging analytics database with rows for at least two distinct values of the field that will drive access, such as a region or business unit column. The Superset admin then registers that table as a dataset and creates two or three test accounts, each assigned to one of the roles that will be restricted. Use synthetic data only, so no production records are copied into staging. This step is done when the test accounts exist, each is mapped to its role, and the dataset loads for an admin user with all rows visible.

  3. Define RLS filter rules with roles and group keys

    The Superset admin opens the row level security settings and creates one filter per restriction, choosing whether it is a regular filter or a base filter and attaching it to the test dataset. Each filter gets a clause, such as a WHERE condition on the test column, and is assigned to the roles it should apply to, with a group key where filters need to be grouped for combination logic. Record how filters combine, since multiple regular filters in the same group are joined with OR while different groups and base filters are joined with AND, and confirm this behavior against the Superset docs for the version in use. This step is done when the rule list is documented with each filter's type, clause, roles and group key.

  4. Verify role-specific rows in charts

    Each test account opens a chart built on the test dataset and checks the row count and the distinct values of the restricted column against the expected results written down in advance. The admin account is used as the control, and a role with no matching filter should show all rows, which confirms the rule is not applied too broadly. Any mismatch is traced back to the filter's role assignment or clause before moving on. This step is done when every test account's chart output matches its expected rows and the results are saved for the evidence record.

  5. Verify role-specific rows in SQL Lab

    Each test account runs a simple SELECT against the test table in SQL Lab, using the database connection it is permitted to use, and compares the returned rows with the chart results from the previous step. This check matters because SQL Lab queries are a separate path from chart queries, and a restriction that holds in charts can still need review for direct SQL access. Confirm with the Superset docs for the version in use whether your SQL Lab permissions expose the dataset, and note any role that can bypass the filter through direct queries. This step is done when SQL Lab results match the chart results for each role, or any gap is logged with an owner and a fix.

  6. Check dashboards with native filters

    The Superset admin places the test charts on a dashboard that uses native filters, then each test account opens the dashboard and changes the native filter values to confirm that the row level restriction still applies and cannot be widened by a user-selected filter. The tester also checks that default filter values do not reveal rows outside the account's role. Record which native filters were tested and what each role saw. This step is done when every test account's dashboard view matches its expected rows across all native filter combinations tested.

  7. Record test evidence and approve rollout

    The security or compliance lead collects the expected results, chart and SQL Lab outputs, dashboard observations, filter configuration and group-to-role mapping into one dated test record, and signs off on the scope of what was tested. The record should also list any roles or paths not covered and the agreed action for each. Repeat the sequence in the production environment after any change to filters, roles or the identity mapping. This step is done when the signed record exists and the owner of each open item is named.

RLS configuration options and when each fits

This table compares the four RLS approaches named in the Superset documentation: regular filters, base filters, group keys and Jinja user filters. Read each row against your access model to see where it fits, what it costs to administer and where a misconfiguration would expose or hide rows. Most deployments combine a regular or group-key design with one carefully reviewed base filter.

OptionBest fitAdmin and maintenanceMain risk
Regular filterLimiting a dataset to rows for specific roles, such as one region or business unit, with the same clause for every memberAssign roles to each filter; every new role or dataset needs an entry reviewed by its ownerA role left off the filter sees unfiltered rows, and overlapping filters are hard to trace
Base filterA default restriction that applies to users who match no regular filter, such as hiding sensitive rows unless a role is exemptOne entry per dataset; exempt roles must be listed on purpose and reviewed when roles changeA missing regular filter turns into a silent restriction for everyone else, which can break dashboards
Group keyCombining filters so a user sees rows matching any one filter in a set, such as two regions granted through separate rolesEach filter in the set needs the same group key; document key names and who owns themFilters in different groups combine with AND, so adding a key to one filter can narrow results unexpectedly
Jinja user filterRows tied to the signed-in user, such as an owner column matched to current_usernameOne filter serves many users, but clause changes need SQL review and tight dataset edit rightsThe clause is SQL; a wrong column, empty owner values or identity mismatches can leak or hide rows

Security and operational risks of RLS in Superset

Row level security in Superset only holds if the people who can change datasets, filters and queries are controlled, and if every path to the data passes through the same rules. The cards below cover the places where filters are most often bypassed or drift over time, from editing rights and direct database access to caches, exports and change records.

Filter editors define the boundary

RLS is only as strong as the users who can create or edit RLS filters and the datasets they apply to. A user who can change a filter clause, or who can point a dataset at a different table, can widen what others see without touching a dashboard. Review which roles hold the permissions to manage row level security and dataset edits, and keep those roles small and separate from dashboard authoring. Confirm this in your own environment by testing an account that only has dashboard edit rights.

Direct database access bypasses filters

Superset applies RLS filters inside its own queries. Anyone who connects to the warehouse with a database account, a BI tool, a notebook or a shared credential reads the full tables and ignores every filter. Map which database accounts exist outside Superset, restrict them to the rows and schemas they need, and treat any credential that can reach the underlying tables as part of the RLS design, not a separate concern.

SQL Lab and chart SQL escape scope

Users with SQL Lab access or chart-level custom SQL can write queries that do not go through the filters a dashboard user sees. Decide which roles may run ad hoc SQL against each database, and whether analysts working in SQL Lab need the same row restrictions as dashboard viewers. Check each restricted dataset for query paths that accept raw SQL, and limit those paths for users outside the data owner group.

Cache and exports carry rows across viewers

Cached query results and exported files are copies of filtered data. If a cache key does not account for the viewer's filter context, one user's results can be served to another. Exports to CSV, Excel or image files then move rows outside Superset entirely. Verify that caching is scoped to the filter context for restricted datasets, and decide whether exports and scheduled reports should be allowed for those datasets at all.

Filter changes need change control

A single edit to a filter clause, group key or Jinja expression can change what hundreds of users see. Treat RLS definitions like access policy: record who proposed the change, who approved it, and the before and after clause. Keep filter definitions in version-controlled files where your process allows it, and require a test pass against named test accounts before each change goes live.

Audit logs must show filter history

Auditors will ask who could see which rows at a given time, and the answer depends on logs of role membership, filter edits and dataset changes. Confirm which of these events your Superset deployment records, where the logs are stored, how long they are kept, and whether they can be exported to your central logging system. Gaps in this history are often what makes a row-level control hard to evidence after the fact.

Questions teams ask before rolling out Superset RLS

How much does it cost to set up row level security in Superset?

Cost depends on how many datasets need filters, how many groups and roles must see different rows, and whether your identity provider already carries the attributes the filters need. The main cost is the time to design the filter model, write and review each filter clause, and test every role against real data. Infrastructure cost is usually small because RLS runs inside Superset's existing query path. No public figure exists for this work, so ask any partner for a fixed-scope quote built from your dataset count, group count and number of test cases, and confirm which parts are one-time (design, build, testing) and which recur (new datasets, role changes, periodic review).

How long does it take to implement Superset RLS?

Duration follows the same drivers as cost: the number of governed datasets, the complexity of the access rules, and how clean your source data and group membership are. A small set of datasets with one clear key per group is far quicker to finish than a multi-tenant model with nested business rules. No researched duration applies, so confirm the timeline in writing with your partner or internal team and ask which milestones include review and test sign-off rather than only configuration.

What does the work need from our side?

Three inputs decide most of the schedule. First, data owners must state which rows each group may see, in business terms, and sign off on the rules. Second, someone must map identities: which Superset groups or roles correspond to which business units, and which attribute, such as a region or tenant code, identifies a user's rows. Third, you need test accounts, one per representative role, with known expected results. Without these, the build stalls on interpretation rather than configuration.

Can our internal team set up Superset RLS without an outside partner?

Yes, if your team already runs Superset, understands its roles and the SQL behind your datasets, and can write and review filter clauses. Teams often struggle with three areas: deciding which filters are regular and which are base filters, predicting how filters combine for users in several groups, and testing that a filter does not expose rows to the wrong role. An outside partner is most useful for the design review and the test plan, which an internal owner can then carry forward. Confirm your team's capacity before deciding, since RLS rules need maintenance as datasets and roles change.

How does Superset RLS differ from row policies in the database?

Superset RLS filters rows in the queries Superset sends, based on rules you define in the Superset metadata for particular roles. Native database row policies, such as those in PostgreSQL, are enforced by the database engine for every client that connects with a given role, including BI tools, scripts and direct SQL sessions. Superset RLS does not protect data from users who can reach the database by another path. For strong isolation, many teams combine both: database policies for the hard boundary and Superset RLS for the dashboard experience. Confirm the database's policy support and your access paths before choosing.

What testing evidence should we expect before wider rollout?

Expect a written test matrix that lists each dataset, each role or group, the filter applied, and the expected row count or sample values, with results recorded for a test account in each role. Good evidence also shows that users in several groups receive the combined result you intended, that base filters apply to SQL Lab and charts consistently, and that changes to group membership take effect as expected. Ask for the test scripts or queries, the sign-off record from the data owner, and a retest plan for future dataset or role changes.

What are the most common RLS mistakes engineers should check for?

Common mistakes include filters that apply to a dataset but not to the charts built on it, base filters that a user with a broad role can bypass, and clauses that assume one group per user when users belong to several. Check that the filter clause is valid for the target SQL dialect, that the key column is indexed for large tables, and that test accounts are not accidentally in admin roles that skip filtering. Also confirm that anyone who can edit datasets understands how templated filters change the query, because RLS and Jinja templating interact.

How DeployOpen scopes RLS work for Superset

RLS work is agreed in writing before any filter is written. DeployOpen's engagements are fixed-scope, so scope, deliverables and timelines are set in a document both sides sign before work starts. For row level security, that written scope usually lists the datasets in question, the roles and groups that will see filtered data, the filter rules for each dataset (regular or base, with the group keys and Jinja expressions they depend on), and the test plan that proves each role sees only its own rows. A quote follows from that scope, so the more precisely the datasets, roles and test cases are named, the more precise the quote can be. Ask for these items explicitly in any proposal, including who owns the test accounts and where the test results will be kept.

Some decisions belong to your team, and the scope should record them. Your data owners decide which attribute defines access, such as region, business unit or customer account, and who approves a change to a filter. Your identity team decides how group membership reaches Superset, which affects whether filters can rely on group keys at all. These answers shape the build and should be confirmed before the quote is final, because a rule that depends on an unmanaged attribute tends to be the one that gets reopened later. The written scope should also state what happens when a new dataset or role is added after go-live, and whether that work is covered by the original agreement or a retainer.

How DeployOpen delivers and supports Superset RLS

DeployOpen plans and builds row level security for a self-hosted Apache Superset inside your own infrastructure, starting from the access model your data owners already use. Each stage ends in written deliverables, so filter logic, test evidence and operating notes stay with your team after the engagement.

How we scope

  • Map which datasets hold regulated or sensitive rows and which groups or roles should see which subsets.
  • Agree in writing which filters are regular and which are base filters, and how they combine per dataset.
  • Confirm the identity source, group names and any Jinja user attributes that filters will depend on.

How we build

  • Configure RLS filters per dataset, with group keys and clauses reviewed against the agreed access model.
  • Test filter behavior with representative test accounts across dashboards, charts and SQL Lab before wider release.
  • Document the filter catalog, its owners and the change process for adding or editing filters.

How we hand over

  • Deliver a filter register, test scripts and results, and a record of decisions made during the build.
  • Walk your administrators through how filters are edited, reviewed and removed without breaking dashboards.
  • Agree in the written scope which tests your team will repeat after Superset upgrades or dataset changes.

How we support

  • Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
  • Ongoing support, upgrades and continuous testing are available as a retainer, scoped separately from the build.
  • Retainers can cover re-testing RLS after Superset version changes, using the upgrade steps your team follows.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.