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:
- 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.
-
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 aWHEREclause 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.
ORG_ACME
alice@acme.com
emea
sales
manager
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
-
01
Open the dashboard configuration
In Embedportal, go to Navigation, open the dashboard, and scroll to the Security panel.
-
02
Toggle “Enable RLS”
RLS is only available when the embed mode is Authenticated. If you’re on Anonymous, switch modes first.
-
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 addregion; role-based visibility addsrole. -
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=vieweron a read-only public dashboard, regardless of the caller’s actual role. - Fallbacks — set a
defaultValueused when the viewer’s profile field is empty.
11. Verify and audit
After enabling RLS, always run the two-tenant test before shipping:
- Create two test users in two different tenants with at least one distinguishing row in each.
- Sign in as the first; confirm only that tenant’s rows appear.
- Sign in as the second; confirm the other tenant’s rows appear — and crucially, nothing from the first.
- 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.