Skip to main content
Version: Next

Embedding Superset

Superset dashboards can be embedded directly in host applications using the @superset-ui/embedded-sdk package.

Prerequisites
  • The EMBEDDED_SUPERSET feature flag must be enabled.
  • The embedding domain and allowed origins must be configured by an admin.

Quick Start​

Install the SDK:

npm install @superset-ui/embedded-sdk

Embed a dashboard:

import { embedDashboard } from '@superset-ui/embedded-sdk';

embedDashboard({
id: 'dashboard-uuid-here', // from Dashboard → Embed
supersetDomain: 'https://superset.example.com',
mountPoint: document.getElementById('superset-container'),
fetchGuestToken: () => fetchTokenFromYourBackend(),
dashboardUiConfig: {
hideTitle: true,
filters: { expanded: false },
},
});

fetchGuestToken must return a guest token obtained from your server by calling Superset's /api/v1/security/guest_token/ endpoint with a service account. Do not call this endpoint from client-side code.


Callbacks​

resolvePermalinkUrl​

When a user copies a permalink from an embedded dashboard, Superset generates a URL on its own domain. In an embedded context this URL is usually not meaningful to the host application's users — the dashboard is rendered inside the host app, not at the Superset URL.

The resolvePermalinkUrl callback lets the host app intercept permalink generation and return a URL on the host domain instead:

embedDashboard({
id: 'my-dashboard-uuid',
supersetDomain: 'https://superset.example.com',
mountPoint: document.getElementById('superset-container'),
fetchGuestToken: () => fetchGuestToken(),
/**
* Called when Superset generates a permalink.
* @param {Object} args - { key: string } — the permalink key
* @returns {string | null} - your host URL, or null to use Superset's default
*/
resolvePermalinkUrl: ({ key }) => {
return `https://myapp.example.com/dashboard?permalink=${key}`;
},
});

If the callback returns null or is not provided, Superset uses its own permalink URL as a fallback.

This rewrite only applies to the non-embedded permalink path — it has no effect on embedded dashboards. When Superset is not embedded, it rewrites the origin of any permalink URL it generates to window.location.origin before showing it to the user, which keeps a proxied or subdirectory-deployed Superset from handing out a permalink that points at an internal hostname the user's browser can't reach.

When Superset is embedded, this rewrite is skipped entirely regardless of the flag below: a resolvePermalinkUrl callback's return value is used as-is, and if no callback is provided (or it fails), the backend-supplied URL is also returned as-is.

If your reverse proxy correctly forwards X-Forwarded-Host and you'd rather non-embedded permalinks carry the backend's literal origin, opt out of the rewrite with EMBEDDED_DISABLE_PERMALINK_ORIGIN_REWRITE:

# superset_config.py
EMBEDDED_DISABLE_PERMALINK_ORIGIN_REWRITE = True

This defaults to False (rewrite enabled) and only affects non-embedded permalinks. Flipping the default would regress the common proxied/subdirectory deployment by exposing an unreachable internal host in copied permalinks.


Feature Flags for Embedded Mode​

DISABLE_EMBEDDED_SUPERSET_LOGOUT​

Hides the logout button when Superset is embedded in a host application. This is useful when the host application manages the session lifecycle and you do not want users to accidentally log out of the embedded Superset session:

# superset_config.py
FEATURE_FLAGS = {
"EMBEDDED_SUPERSET": True,
"DISABLE_EMBEDDED_SUPERSET_LOGOUT": True,
}

When enabled, the Logout menu item is removed from the user avatar dropdown in the embedded view. The session can still be invalidated server-side by revoking the guest token.

EMBEDDED_SUPERSET​

Must be True to enable the embedded SDK and the guest token endpoint. Without this flag, embedDashboard will fail to load.

EMBEDDED_CREDENTIAL_FALLBACK​

Allows a database connection that authenticates logged-in users per-user via OAuth2 to also carry a single username and password used only for embedded guest requests.

This exists because the two authentication models do not meet. An embedded viewer signs in with a guest token rather than a Superset account, so there is no per-user OAuth2 token to resolve for them — and an external viewer may have no identity on the analytical database at all. Without a fallback, embedded dashboards on a per-user OAuth2 connection cannot run queries.

# superset_config.py
FEATURE_FLAGS = {
"EMBEDDED_SUPERSET": True,
"EMBEDDED_CREDENTIAL_FALLBACK": True,
}

With both flags on, engines that support it (currently Snowflake) show an Embedded guest credentials section in the connection dialog. The credential is stored encrypted; the password is masked on read, and the username stays visible so an administrator can see which database user embedded queries run as.

Understand what this grants before enabling it:

  • Every embedded viewer of that connection queries as that one database user. Guest tokens carry no database identity, so per-user attribution and any database-side row-level security keyed to the user do not apply. Use a dedicated account with the narrowest access the embedded dashboards need, and enforce per-viewer restrictions with Superset's own row-level security rules in the guest token.
  • Logged-in users are unaffected. They continue to authenticate individually via OAuth2 and have no route to the stored credential.
  • The guest token's username claim is never used to connect. Whoever mints the token controls that claim, so it is deliberately kept out of the connection identity.
  • Turning the flag back off is a kill switch, not a deletion: the stored credential stops being offered and stops being used, but is preserved.

URL Parameters​

The following URL parameters can be passed through the urlParams option in dashboardUiConfig or appended to the embedded iframe URL:

ParameterValuesEffect
standalone0, 1, 2, 30: normal; 1: hide nav; 2: hide nav + title; 3: hide nav + title + tabs
show_filters0, 1Show or hide the native filter bar
expand_filters0, 1Start with filter bar expanded or collapsed

Embedding a Single Chart​

Individual charts can also be embedded standalone, outside of a dashboard, using a chart permalink. From Explore, generate a permalink for the chart, then append URL parameters to it:

/explore/p/<permalink-key>/?standalone=1&show_download=1
ParameterValuesEffect
standalone0, 10: normal Explore view; 1: hide the Explore header and controls
show_download0, 1Show a compact download control (CSV, JSON, Excel) on the standalone chart

show_download is opt-in and has no effect outside of standalone=1. The download control still respects the viewer's export permissions — it's hidden for users who lack them even when the parameter is set. With the GRANULAR_EXPORT_CONTROLS feature flag enabled, this requires the can_export_data permission on Superset; otherwise it falls back to can_csv on Superset.

Explore's Embed Code button on a chart also generates one of these permalink URLs wrapped in an <iframe>, giving you a session-authenticated iframe embed. That's a separate flow from dashboard embedding above: it doesn't go through @superset-ui/embedded-sdk, guest tokens, or the dashboardUiConfig options — the viewer needs an existing Superset session with the can read on Explore permission, in addition to access to the chart itself. Viewing the same chart on a dashboard doesn't require that permission, so a role scoped only for dashboard viewing gets an access denial on this URL.

One caveat when the host page lives on a different site than Superset: the default SESSION_COOKIE_SAMESITE = "Lax" setting keeps the session cookie out of cross-site iframe requests, so the viewer lands on the login page instead of the chart. Serving both from the same site avoids this; otherwise set SESSION_COOKIE_SAMESITE = "None" together with SESSION_COOKIE_SECURE = True and allow the host origin in your TALISMAN_CONFIG frame-ancestors. Even with that configuration, browsers that block third-party cookies by default (including Safari) can still redirect the viewer to the login page. For those cases, host the iframe on the same site as Superset, or use the dashboard embedding SDK's guest-token flow above instead.


Security Notes​

  • Guest tokens expire — their lifetime is controlled by the GUEST_TOKEN_JWT_EXP_SECONDS config (default: 5 minutes). Refresh tokens before they expire using a token refresh mechanism in your host app.
  • Datasource scope — chart and native-filter access is bound to both the datasource type and its identifier. Legacy native-filter targets without a type refer to SQL datasets. When the optional guest-token datasets allowlist is present, only the listed SQL datasets are reachable and semantic views are denied.
  • Row-level security — pass rls rules in the guest token request to restrict which rows are visible to the embedded user. Semantic views cannot enforce guest-token SQL clauses, so queries and cached-result reads are rejected when a global rule or a rule scoped to the semantic view applies. For hosts, a global guest rule deliberately refuses every semantic view, and a dataset-scoped rule can also refuse a semantic view even when the rule was intended for a SQL dataset. Read permissions do not override these restrictions. Semantic views remain accessible when no guest rule applies; SQL datasets continue to enforce their applicable rules.
  • Allowed domains — restrict which host origins can embed a dashboard by setting Allowed Domains per-dashboard in the Embed settings modal. Superset checks the request's Referer header against this list before serving the embedded view; an empty list allows any origin, so configure this explicitly for production.
  • Redacted errors — API responses to a guest token report a generic An error occurred while fetching the data. instead of the underlying error, since engine errors quote catalog, schema, table and column names. Errors Superset raises itself — access denials, timeouts, payload validation — keep their message, and the full error is always available in the server logs.
  • OAuth2 connections and guests — a guest cannot complete an OAuth2 authorization, so Superset does not start one for them. An embedded viewer on an OAuth2 connection with no applicable credential gets the database driver's own authentication error rather than being sent into a login flow they cannot finish. To serve embedded dashboards from such a connection, see EMBEDDED_CREDENTIAL_FALLBACK.

Guest-token request-header size diagnostics​

A successful guest-token mint does not guarantee the token can pass through your deployment's proxies. Limits apply to the encoded JWT bytes plus header overhead, not the number of RLS rules or identifiers. A proxy can reject the subsequent authentication request before it reaches Superset, including an HTTP 400 HTML response instead of JSON. A 400 alone does not establish a size problem.

Operators can set a deployment-specific diagnostic budget in superset_config.py:

# Example only: choose a budget for your complete proxy path.
GUEST_TOKEN_HEADER_MAX_BYTES = 16 * 1024

The default is None (no budget warnings). Positive integer budgets count UTF-8 bytes of GUEST_TOKEN_HEADER_NAME, : , the encoded token, and \r\n (four framing bytes). Only sizes strictly greater than the budget warn; equality does not. This is consistent diagnostic accounting, not a prediction of every proxy's wire-level accounting, HTTP/2 compression, or total-header limits. Leave a safety margin and validate your actual deployment, including custom header names. Zero, negative, non-integral, or non-numeric values (including strings and booleans) disable budget warnings, as do values above JavaScript's maximum safe integer (2^53 − 1). Whole-number floats are accepted. Convert environment-variable strings to integers in deployment configuration to enable the budget.

Issuance audit metadata includes token_bytes, header_bytes, header_budget_bytes, and header_budget_exceeded. Issuance remains HTTP 200 with the same token and response shape. The embedded bootstrap exposes the budget and configured header name; reload the iframe after changing deployment config. The embedded client measures initial and refreshed tokens and warns in the developer console with sizes only. Initial authentication failures get a targeted suggestion only when the request's token exceeds the budget and the failure has no status or HTTP 400/431/494; other statuses and ambiguous in-flight refreshes use the generic error. Refresh warnings do not restart authentication. These diagnostics do not record JWTs, decoded claims, RLS SQL, or request headers.

AWS Application Load Balancer quotas list a non-adjustable 16 K single-header limit. Increasing a Superset diagnostic budget does not increase that limit or add large-token support.

To reduce payload size, replace large inline RLS ID lists with a compact entitlements-table subquery where supported by your database. Keep the same tenant/user restrictions, derive identity from your trusted token-issuing backend, and verify equivalent row access and query performance before rollout. Do not remove RLS or broaden entitlements to make a token smaller.