GitHub user LiamTorrelli added a comment to the discussion: Superset Embedded
SDK
Short version of what the embedded SDK actually does, and then the tenant-role
question — because that's the part that trips people up.
**What it's for**
`@superset-ui/embedded-sdk` mounts a Superset dashboard in a cross-origin
`<iframe>` inside your app. The user never logs into Superset directly. Your
backend mints a short-lived **guest JWT**, the SDK passes it over
`postMessage`, and Superset spins up an anonymous session inside the frame.
Superset does **not** hand guest tokens to the browser. Your app calls
`/api/v1/security/guest_token/` server-to-server (with a privileged service
account), gets the JWT back, and your `fetchGuestToken` callback returns it to
the client.
Minimal client side:
```javascript
import { embedDashboard } from "@superset-ui/embedded-sdk";
embedDashboard({
id: "<dashboard-uuid-from-embed-modal>",
supersetDomain: "https://superset.example.com",
mountPoint: document.getElementById("analytics-container"),
fetchGuestToken: () =>
fetch("/api/superset-guest-token").then((r) => r.text()),
dashboardUiConfig: { hideTitle: true },
});
```
Server side you POST something like:
```json
{
"user": { "username": "tenant_acme_viewer" },
"resources": [{ "type": "dashboard", "id": "<uuid>" }],
"rls": [{ "clause": "tenant_id = 'acme'" }]
}
```
Signed with `GUEST_TOKEN_JWT_SECRET`. Default expiry is 300 seconds.
**Your tenant-role question**
No — a guest token does **not** map to your existing tenant FAB roles the way
normal DB auth does.
Every guest session gets whatever role `GUEST_ROLE_NAME` points at (default
`Public`, a lot of teams bump it to `Gamma` when charts come back empty). Your
per-tenant roles in Superset are bypassed for the iframe session.
Multi-tenant access is enforced in **your token-minting code**, not by picking
a Superset role:
1. User logs into **your** app (DB auth, SSO, whatever).
2. Your backend resolves tenant → allowed dashboard UUIDs for that tenant.
3. You mint a guest token whose `resources` list only includes those
dashboards, and whose `rls` clauses scope the SQL (e.g. `organization_id =
123`).
4. Optional: `GUEST_TOKEN_VALIDATOR_HOOK` in `superset_config.py` to reject
tokens that arrive without tenant scoping.
So tenant A never gets tenant B's dashboards because your API never puts them
in the payload — not because Superset evaluated their FAB role inside the
iframe.
The trap: treating the guest token as "extend my logged-in user into Superset."
It's a second auth system. Your app's session and the iframe JWT are parallel.
RLS in the token is synthetic — whatever string your backend injects gets
compiled into every query. Stale or missing clauses leak data even when the UI
looks fine.
**Before it works at all**
`EMBEDDED_SUPERSET = True`, rotate `GUEST_TOKEN_JWT_SECRET`, CORS +
Talisman/`frame-ancestors`, and add your parent origin in the dashboard Embed
modal **Allowed Domains**. Missing any of those and you'll debug iframe errors
before you ever get to tenant logic.
We wrote up the full flow — `embedDashboard()` lifecycle, postMessage
handshake, RLS, and all nine server switches:
https://www.drafted.work/blog/superset-embedded-sdk-guest-tokens
GitHub link:
https://github.com/apache/superset/discussions/36975#discussioncomment-17322069
----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]