Skip to content

Double RLS application in virtual datasets for guest users (regression from PR #36061) #37359

Closed

Description

@YuriyKrasilnikov

Bug description

Summary:
PR #36061 "fix: RLS in virtual datasets" introduced a regression causing double RLS application for guest users with embedded dashboards. This is similar to #34894 (double time filter application) fixed in PR #35890.

Steps to Reproduce:

  1. Create a physical dataset for table my_table
  2. Create a virtual dataset with SQL referencing that table:
    SELECT * FROM my_schema.my_table WHERE some_column = 'value'
  3. Create a dashboard with a chart using this virtual dataset
  4. Generate a guest token with RLS clause: tenant_id = 123
  5. Open the embedded dashboard with this guest token
  6. Observe SQL error with incorrect table alias

Expected behavior:
RLS should be applied once - either to the underlying table OR to the virtual dataset output.

Actual behavior:
RLS is applied twice:

  1. First by apply_rls() in models/helpers.py:2047-2057 (wraps underlying table in subquery)
  2. Second by get_sqla_row_level_filters() in models/helpers.py:3198 (adds WHERE clause to virtual dataset query)

Generated SQL example:

SELECT ... FROM (
  SELECT * FROM my_schema.my_table
  WHERE tenant_id = 123  -- First RLS applied to underlying table (correct)
) AS `my_schema.my_table`
WHERE my_table.tenant_id = 123  -- Second RLS applied with WRONG alias!
GROUP BY ...

The second WHERE clause uses my_table.tenant_id but the subquery is aliased as my_schema.my_table, causing SQL errors like:

Unknown expression or function identifier 'my_table.tenant_id'

Root Cause:

  • get_from_clause() in models/helpers.py:2047-2057 calls apply_rls() which wraps tables referenced in virtual dataset SQL with subqueries containing RLS predicates
  • get_sqla_query() in models/helpers.py:3198 calls get_sqla_row_level_filters() which adds guest token RLS to the outer WHERE clause
  • For guest users with embedded dashboards, both mechanisms fire independently, causing double application with mismatched aliases

Related:

Screenshots/recordings

N/A - backend SQL generation issue

Superset version

6.0.0

Python version

3.11

Node version

18 or greater

Browser

Not applicable

Additional context

  • Feature flags enabled: EMBEDDED_SUPERSET
  • This is a regression - worked correctly in Superset 5.x
  • No configuration workaround available
  • Workaround: use physical datasets instead of virtual datasets (not always possible)

Checklist

  • I have searched Superset docs and Slack and didn't find a solution to my problem.
  • I have searched the GitHub issue tracker and didn't find a similar bug report.
  • I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.

Activity

  1. changed the title [-]fix: Double RLS application in virtual datasets for guest users (regression from PR #36061)[/-] [+]Double RLS application in virtual datasets for guest users (regression from PR #36061)[/+] on Jan 22, 2026
  2. dosubot commented on Jan 22, 2026

    @dosubot

    This regression happens because RLS is applied twice for guest users with embedded dashboards using virtual datasets: once by wrapping the underlying table in a subquery with RLS predicates (apply_rls()), and again by adding RLS filters to the outer query (get_sqla_row_level_filters()). This double application leads to SQL alias mismatches and errors, since the outer WHERE clause references an alias that doesn't exist after the subquery rewrite. The pattern is nearly identical to the previously fixed double time filter bug (PR #35890). There’s currently no config workaround except using physical datasets, which isn’t always practical. No open PR or issue addresses this regression yet, so a fix will likely require logic to prevent RLS from being applied twice in this scenario—potentially by detecting when RLS has already been pushed down into the subquery and skipping the outer filter application.
    You can review the relevant code and logic in models/helpers.py and superset/utils/rls.py.

    To reply, just mention @dosu.


    How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other

    Chat with Dosu Open in Cursor Join Discord Share on X

  3. added a commit that references this issue on Jan 23, 2026
    b8c3448
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions