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]

Reply via email to