Superset dashboard embedded in DHIS2 shows "No data" only when RLS org-unit filter is applied via guest token

Hi all,

We’re piloting an embedded analytics approach for our HMIS: rather than pushing data back into DHIS2 (we’ve been hitting issues with category combos and append-only data pushes requiring full delete/re-upload cycles), we’re embedding Apache Superset dashboards directly into the DHIS2 Dashboard app, sourcing data from our own SQL Server warehouse.

Setup:

  • DHIS2 instance with a custom Spring Boot integration service that requests Superset guest tokens for embedding (via /api/v1/security/guest_token/), passing a Row Level Security (RLS) clause dynamically per user based on their assigned DHIS2 org unit(s).
  • Users can be assigned org units at national, regional, or facility level, and some users have multiple facility assignments.
  • We’ve built an OrgUnitHierarchyPath column into our Superset dataset (e.g. OUNESWATINI/OURegHHOHHO/OUFcltyH001) so a single LIKE '%<org_unit_code>%' filter can match at any level of the hierarchy.

The problem:
When accessing the dashboard directly in Superset (own login, no guest token), the dataset and charts return data correctly. But when the same dashboard is embedded in DHIS2 via a guest token — with the dynamic RLS clause attached — every chart shows “No data,” even for a user assigned to the top-level national org unit, which should match every row.

There is no static rule configured under Settings → Row Level Security in Superset — the RLS filtering is being injected entirely at guest-token request time by our backend service, which logs confirmation that it’s building and attaching the clause (e.g. Set org unit hierarchy RLS for user: 'Sakhile', org units: 'OUNESWATINI') before requesting the token.

What we’ve ruled out so far:

  • The underlying SQL query returns data correctly when run directly (confirmed in SQL Lab).
  • The dataset/chart definitions match what’s expected — no stale dataset pointer.
  • Not a caching issue — confirmed via force refresh.
  • Not a static RLS rule — none exists.

This points to the issue being in how the guest-token RLS clause itself is constructed or transmitted, but we wanted to check whether anyone in the community has:

  • Implemented a similar DHIS2-org-unit-to-Superset-RLS integration before, and if so, what clause format / guest token payload structure worked for you.
  • Encountered a similar “works logged in directly, fails via guest token” pattern, and what turned out to be the cause.
  • Any guidance on the exact expected format Superset’s guest token rls array expects (e.g. does the clause need to reference the dataset’s column exactly as named, any quoting/escaping gotchas, dataset ID scoping per RLS entry, etc.)

Hi Sakhile,

This does sound like the guest-token RLS path rather than the dataset itself, especially since the same charts work with a normal Superset login.

Superset’s guest-token API expects rls as an array of objects containing at least a clause, with an optional dataset ID, for example:


"rls": [
  {
    "clause": "OrgUnitHierarchyPath LIKE '%OUNESWATINI%'",
    "dataset": 123
  }
]

The dataset value should be the Superset dataset ID, not the database/table ID. Superset also supports leaving dataset out, in which case the rule is not scoped to a single dataset.

A few things I’d test:

  • Generate a guest token with a very simple clause such as 1 = 1. If that still returns no data, the problem is probably not your org-unit LIKE expression.
  • Then test a hard-coded clause such as OrgUnitHierarchyPath LIKE '%OUNESWATINI%' before introducing the dynamically generated value.
  • Confirm the column name and quoting are valid for SQL Server exactly as Superset generates the query.
  • If you include dataset, confirm it matches the dataset used by every affected chart.

It would also be worth checking the Superset server logs while loading the embedded dashboard. Recent Superset documentation notes that embedded guest-token errors may be redacted in the frontend while the underlying database/query error remains available in the server logs.

There have also previously been Superset issues specifically involving guest-token RLS where embedded dashboards failed despite working normally without RLS, so if even 1 = 1 reproduces it, I’d consider raising an issue with Superset rather than DHIS2, including the Superset version, sanitized guest-token payload and server-side error.

The DHIS2 side here is probably just the embedding host; the key diagnostic is whether the same Superset embedded dashboard + guest token fails outside DHIS2 as well.