Embedportal a subproduct of atSpark
Product Features Security Use cases Pricing Docs
Sign in Start free

Home / Docs / Row-level security

Row-level security
for embedded dashboards.

One set of rules. Forwarded into Tableau User Attributes, Power BI Effective Identities, and QuickSight session tags automatically. A practical guide to scoping every row a viewer sees, with the exact calculated fields and JSON shapes you need.

Published
2026-04-17
Reading time
10 min
Level
Intermediate
Applies to
Tableau · Power BI · QuickSight · Metabase

On this page

  1. 1. What RLS is
  2. 2. Why SaaS embedding needs it
  3. 3. The Embedportal model
  4. 4. Available attributes
  5. 5. Enable RLS on a dashboard
  6. 6. Wire RLS in Tableau
  7. 7. Wire RLS in Power BI
  8. 8. Wire RLS in QuickSight
  9. 9. Wire RLS in Metabase
  10. 10. Per-dashboard overrides
  11. 11. Verify & audit
  12. 12. Common pitfalls
  13. 13. FAQ

1. What row-level security is

Row-level security (RLS) filters the rows a dashboard returns based on who is viewing it. The dashboard definition — the charts, the calculations, the layout — stays identical. What changes is the underlying query’s WHERE clause.

Alice in the Acme tenant logs in and sees Acme rows only. Bob in Globex logs in and sees Globex rows only. Same URL, same workbook, different data.

2. Why multi-tenant embedding needs RLS

If you ship a single Tableau workbook to a single tenant, authentication is enough — only their users can open it. The moment you host one dashboard for many tenants, that stops working. You need a mechanism that:

  • Filters at query time, not at render time — bytes never leave the database that shouldn’t.
  • Can’t be bypassed client-side — tampering with a URL or cookie shouldn’t grant access.
  • Scales to thousands of tenants without creating a workbook per tenant.

RLS is that mechanism. And critically for embedded analytics: every major BI vendor supports it, but each in its own way. Embedportal normalises the configuration.

3. The Embedportal model

Embedportal models RLS in two layers:

  1. The claims — a set of attributes about the viewer (tenant, region, role, etc.) that travel as JWT claims on every embed request. Defined in your user profile, enriched by your backend, signed by Embedportal.
  2. The rule — the filter, defined once on the BI vendor’s data source. Reads the claim via USERATTRIBUTE() (Tableau), an Effective Identity (Power BI), or a session tag (QuickSight), and applies a WHERE clause at query time.

You configure the claims once in Embedportal. You configure the rule once per data source in the BI vendor. Every dashboard built on that data source inherits the filter.

4. Available attributes

Standard attributes ship with Embedportal and map to columns on the user profile. Custom attributes are opened up via user tags.

AttributeSourceExample value
organization_id viewer’s current tenant ORG_ACME
user_email viewer’s primary email alice@acme.com
region user profile → region emea
department user profile → department sales
role viewer’s access level manager
custom / tag anything on the user tags list cost_center=CC_042

note — attribute names become JWT claim names verbatim. Pick identifiers that match what your BI vendor expects to read.

5. Enable RLS on a dashboard

  1. 01

    Open the dashboard configuration

    In Embedportal, go to Navigation, open the dashboard, and scroll to the Security panel.

  2. 02

    Toggle “Enable RLS”

    RLS is only available when the embed mode is Authenticated. If you’re on Anonymous, switch modes first.

  3. 03

    Select attributes to forward

    Tick the attributes that your data source depends on. Each ticked attribute becomes a claim on the signed JWT. A typical multi-tenant setup needs only organization_id; geography filters add region; role-based visibility adds role.

  4. 04

    Save

    Save the dashboard. From the next embed request onward, Embedportal signs tokens with the selected claims.

6. Wire RLS in Tableau

Tableau exposes JWT claims to the workbook via USERATTRIBUTE(). Add a calculated field on the data source and use it as a data source filter (not a view filter — data source filters run server-side in the query).

// calculated field: [Organization Filter]
[Organization ID] = USERATTRIBUTE('organization_id')

// calculated field: [Region Filter]
[Region] = USERATTRIBUTE('region')

// calculated field: [Role Filter]
[Access Level] = USERATTRIBUTE('role')

Right-click the data source → Edit Data Source Filters → add each calculated field as TRUE. Publish the workbook.

Tableau will now inject the viewer’s organization_id into every query. If a query tries to return a row from another tenant, the data source filter rejects it.

7. Wire RLS in Power BI

Power BI uses roles defined on the dataset. Each role carries a DAX filter that reads a dynamic user attribute. In the dataset (via Power BI Desktop or service), create a role:

-- Role: "Tenant Scope"
-- Filter applied to the [Organization] table:
[OrganizationId] = USERPRINCIPALNAME()

-- or for custom claims, read from the Effective Identity:
[OrganizationId] = USERPRINCIPALNAME()
&& [Region] = CUSTOMDATA()

Embedportal passes the JWT claims as Effective Identities on the embed token request, so the Power BI service applies the role automatically for the duration of the session.

8. Wire RLS in Amazon QuickSight

QuickSight offers two RLS modes:

  • Dataset-based RLS — you publish a permissions dataset that maps users to values. Works when you have a stable users table.
  • Tag-based RLS — the one Embedportal uses. You define session tags on the embedding session, and the dataset filters on them at query time. Perfect for multi-tenant SaaS because it scales without creating rows per user.

In QuickSight, open the dataset, toggle Row-level security → Tag-based, and declare tag keys like organization_id and region. Embedportal forwards the matching JWT claims as session tags when it calls GenerateEmbedUrlForRegisteredUser.

9. Wire RLS in Metabase

Metabase exposes locked parameters on signed embeds. Open the dashboard, click Sharing → Public link → Embed, mark the tenant and region parameters as Locked.

Embedportal signs the Metabase embed JWT with params filled from the viewer’s claims:

{
  "resource": { "dashboard": 42 },
  "params": {
    "organization_id": "ORG_ACME",
    "region": "emea"
  },
  "exp": 1747486500
}

Because the parameters are locked, viewers cannot edit them in the UI and the Metabase query plan always applies the filter.

10. Per-dashboard overrides

Sometimes two dashboards should filter differently even for the same viewer. A Revenue — EMEA dashboard should always show EMEA rows; a Revenue — APAC dashboard should always show APAC rows — regardless of where the viewer sits.

Embedportal supports per-dashboard overrides. On the dashboard’s Security panel, add an override entry:

{
  "rlsEnabled": true,
  "rlsOverrides": [
    {
      "key": "region",
      "source": "custom",
      "value": "emea"
    }
  ]
}

With source: "custom" the override wins over the viewer’s profile value. With source: "region" (the default) the viewer’s profile supplies the value. Useful shapes:

  • Fixed slice — regional and segment-specific dashboards.
  • Force a role — e.g. always pass role=viewer on a read-only public dashboard, regardless of the caller’s actual role.
  • Fallbacks — set a defaultValue used when the viewer’s profile field is empty.

11. Verify and audit

After enabling RLS, always run the two-tenant test before shipping:

  1. Create two test users in two different tenants with at least one distinguishing row in each.
  2. Sign in as the first; confirm only that tenant’s rows appear.
  3. Sign in as the second; confirm the other tenant’s rows appear — and crucially, nothing from the first.
  4. Inspect the audit log in Embedportal — every embed request shows the claims that were signed into the JWT.

The audit log is searchable by user, dashboard, timestamp, and tenant. Stream it to your SIEM or warehouse for retention beyond Embedportal’s default 13 months.

12. Common pitfalls

  • Dimension filter, not data-source filter — in Tableau the calculated field must be a data-source filter. Dimension filters run after the query, can be overridden, and don’t protect the wire.
  • Case mismatch — USERATTRIBUTE('organization_id') is case-sensitive on the claim name. Match exactly.
  • NULL claim — if a user’s profile field is empty, the JWT claim is missing, and a filter comparing against USERATTRIBUTE() returns NULL, which in many dialects means no rows match. Always set a default in the override.
  • Caching across tenants — Tableau and Power BI cache results keyed by the query plan plus the user attribute. Ensure the attribute is part of the cache key (it is, by default, when used in a data-source filter).
  • Global admins — if you have internal staff who need to see every tenant’s data, sign their tokens without RLS claims from an admin endpoint. Do not hardcode the bypass in the workbook.

13. FAQ

Can a signed JWT be tampered with to bypass RLS?

No. JWTs are signed with a secret that only Embedportal and the backend possess. Any modification invalidates the signature, and the BI vendor rejects the request. As long as the secret is not leaked and tokens are short-lived, RLS cannot be bypassed client-side.

How does Embedportal enforce RLS across different BI vendors?

Embedportal translates one set of RLS attributes into each vendor’s native mechanism: Tableau User Attributes, Power BI Effective Identities, QuickSight session tags, Metabase locked parameters. The configuration you write is the same regardless of vendor.

Do I need to model RLS separately on every dashboard?

No. Rules live on the data source in the BI vendor. Every dashboard built on that data source inherits the filter automatically.

Can I override RLS per dashboard?

Yes. Each Embedportal navigation item can override any attribute’s source — for example, force region=emea on an EMEA-specific dashboard regardless of the viewer’s profile region. See section 10.

Does RLS work with the free public dashboard mode?

No. Anonymous embed mode explicitly has no user claims to filter on. If you need a filtered public view, use an authenticated dashboard with an override that pins the filter to a fixed value.

What happens when the viewer’s profile is missing an attribute?

The JWT claim is omitted. Your filter rule should set a defaultValue on the override, or the underlying data-source filter should treat the missing attribute as “no rows” rather than “all rows”. Fail closed.

Lock down your embeds

RLS is on every plan — Starter, Professional and Enterprise. Start on Professional free for 14 days to add unlimited integrations and 2FA.

Start free trial Book a walkthrough

Related guides

How to embed Tableau dashboards into a SaaS product → All documentation →
© 2026 atSpark Inc. Embedportal is a subproduct of atSpark. Privacy Terms Security Cookies