dosubot[bot] commented on issue #36377:
URL: https://github.com/apache/superset/issues/36377#issuecomment-3605175485

   <!-- Answer -->
   Here’s a concise guide for embedding Superset dashboards with the Embedded 
SDK and guest tokens:
   
   **Minimal working example:**
   ```js
   import { embedDashboard } from "@superset-ui/embedded-sdk";
   
   embedDashboard({
     id: "<dashboard_id>", // UUID from Superset's embed UI
     supersetDomain: "https://your-superset-domain.com";,
     mountPoint: document.getElementById("superset-container"),
     fetchGuestToken: () => fetchGuestTokenFromBackend(), // async function 
returning the JWT
     dashboardUiConfig: {
       hideTitle: true,
       hideTab: true,
       hideChartControls: true,
       filters: { visible: false, expanded: false },
     },
     iframeSandboxExtras: ["allow-top-navigation", 
"allow-popups-to-escape-sandbox"],
     referrerPolicy: "same-origin",
   });
   ```
   
[Reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset-embedded-sdk/README.md#L43-L160)
   
   **Guest token payload example:**
   ```json
   {
     "user": { "username": "viewer" },
     "resources": [{ "type": "dashboard", "id": "<dashboard_id>" }],
     "rls": [],
     "iat": 1730883214,
     "exp": 1732956814,
     "aud": "superset",
     "type": "guest"
   }
   ```
   
[Reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset-embedded-sdk/README.md#L43-L160)
   
   **Required permissions for the read-only role:**
   Grant only these permissions to your custom guest role (start from Gamma, 
remove all edit/export/SQL permissions):
   - `can_read`, `can_list`, `can_show`, `can_get`, `can_external_metadata` on: 
Dashboard, Chart, Dataset, Database, SavedQuery, Query, Embedded Dashboard
   - `can dashboard` and `can explore json` on Superset
   - `can time range` on Api
   - `can read` on DashboardPermalinkRestApi, ExploreFormDataRestApi, 
ExplorePermalinkRestApi
   - `can_access` on Superset (needed for /superset/log endpoint)
   
[Reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/security/manager.py#L322-L2772)
   
   **Superset-side configuration checklist:**
   - Enable the feature flag: `EMBEDDED_SUPERSET = True` in 
`superset_config.py` or `.env`
   - Set a strong `GUEST_TOKEN_JWT_SECRET` and matching 
`GUEST_TOKEN_JWT_AUDIENCE`
   - Set `GUEST_ROLE_NAME = "guest_readonly"` (or your custom role name)
   - Add your embedding domain to allowed domains in the dashboard embed 
settings
   - Enable CORS: `ENABLE_CORS = True` and configure `CORS_OPTIONS`
   - Set up Content Security Policy for iframe embedding:
     ```python
     TALISMAN_ENABLED = True
     TALISMAN_CONFIG = {
         "content_security_policy": {
             "frame-ancestors": ["https://your-embedding-domain.com";],
         }
     }
     ```
   - Restart Superset after config changes
   
[Reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/docs/docs/configuration/networking-settings.mdx#L19-L85)
   
   **Common mistakes and troubleshooting:**
   - Guest token missing required claims (`user`, `resources`, `rls_rules`, 
`type: guest`)
   - Dashboard ID not included in the guest token or in chart data requests 
(causes 403 errors)
   - GUEST_ROLE_NAME not set or not matching your custom role
   - Embedding domain not listed in allowed domains or CSP `frame-ancestors`
   - CORS or X-Frame-Options headers blocking iframe embedding
   - Guest user listed as chart owner (can cause edit options to appear)
   - Charts missing `query_context` field (visit chart edit page in Superset to 
populate)
   - Token expired (`GUEST_TOKEN_JWT_EXP_SECONDS` too short)
   
[Reference](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/security/manager.py#L322-L2772)
   
   If you hit errors like "Guest user cannot modify chart payload," check that 
all charts have a populated `query_context` field and that your guest token is 
correctly scoped.
   
   Let me know if you need more details on any step!
   
   
   <!-- Dosu Comment Footer -->
   *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).*
   
   ---
   <sup>How did I do? 
[Good](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=great_response)
 | 
[Irrelevant](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=irrelevant_answer)
 | 
[Incorrect](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=incorrect_sources)
 | 
[Verbose](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=too_verbose)
 | 
[Hallucination](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=hallucination)
 | [Report 
🐛](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=bug_report)
 | 
[Other](https://app.dosu.dev/response-feedback/beb5e850-e8a6-4544-8dc3-c18c4b313bd4?feedback_type=other)</sup>
   
   [![Chat with 
Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github)&nbsp;[![Open
 in 
Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=Here%E2%80%99s%20a%20concise%20guide%20for%20embedding%20Superset%20dashboards%20with%20the%20Embedded%20SDK%20and%20guest%20tokens%3A%0A%0A%2A%2AMinimal%20working%20example%3A%2A%2A%0A%60%60%60js%0Aimport%20%7B%20embedDashboard%20%7D%20from%20%22%40superset-ui/embedded-sdk%22%3B%0A%0AembedDashboard%28%7B%0A%20%20id%3A%20%22%3Cdashboard_id%3E%22%2C%20//%20UUID%20from%20Superset%27s%20embed%20UI%0A%20%20supersetDomain%3A%20%22https%3A//your-superset-domain.com%22%2C%0A%20%20mountPoint%3A%20document.getElementById%28%22superset-container%22%29%2C%0A%20%20fetchGuestToken%3A%20%28%29%20%3D%3E%20fetchGuestTokenFromBackend%28%29%2C%20//%20async%20function%20returning%20the%20JWT%0A%20%20dashboardUiConfig%3A%20%7B%0A%20%20%20%20hideTitle%3A%20true%2C%0A%2
 
0%20%20%20hideTab%3A%20true%2C%0A%20%20%20%20hideChartControls%3A%20true%2C%0A%20%20%20%20filters%3A%20%7B%20visible%3A%20false%2C%20expanded%3A%20false%20%7D%2C%0A%20%20%7D%2C%0A%20%20iframeSandboxExtras%3A%20%5B%22allow-top-navigation%22%2C%20%22allow-popups-to-escape-sandbox%22%5D%2C%0A%20%20referrerPolicy%3A%20%22same-origin%22%2C%0A%7D%29%3B%0A%60%60%60%0A%5BReference%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset-embedded-sdk/README.md%23L43-L160%29%0A%0A%2A%2AGuest%20token%20payload%20example%3A%2A%2A%0A%60%60%60json%0A%7B%0A%20%20%22user%22%3A%20%7B%20%22username%22%3A%20%22viewer%22%20%7D%2C%0A%20%20%22resources%22%3A%20%5B%7B%20%22type%22%3A%20%22dashboard%22%2C%20%22id%22%3A%20%22%3Cdashboard_id%3E%22%20%7D%5D%2C%0A%20%20%22rls%22%3A%20%5B%5D%2C%0A%20%20%22iat%22%3A%201730883214%2C%0A%20%20%22exp%22%3A%201732956814%2C%0A%20%20%22aud%22%3A%20%22superset%22%2C%0A%20%20%22type%22%3A%20%22guest%22%0A%7D%0A%60%60%60%0A%5BRefere
 
nce%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset-embedded-sdk/README.md%23L43-L160%29%0A%0A%2A%2ARequired%20permissions%20for%20the%20read-only%20role%3A%2A%2A%0AGrant%20only%20these%20permissions%20to%20your%20custom%20guest%20role%20%28start%20from%20Gamma%2C%20remove%20all%20edit/export/SQL%20permissions%29%3A%0A-%20%60can_read%60%2C%20%60can_list%60%2C%20%60can_show%60%2C%20%60can_get%60%2C%20%60can_external_metadata%60%20on%3A%20Dashboard%2C%20Chart%2C%20Dataset%2C%20Database%2C%20SavedQuery%2C%20Query%2C%20Embedded%20Dashboard%0A-%20%60can%20dashboard%60%20and%20%60can%20explore%20json%60%20on%20Superset%0A-%20%60can%20time%20range%60%20on%20Api%0A-%20%60can%20read%60%20on%20DashboardPermalinkRestApi%2C%20ExploreFormDataRestApi%2C%20ExplorePermalinkRestApi%0A-%20%60can_access%60%20on%20Superset%20%28needed%20for%20/superset/log%20endpoint%29%0A%5BReference%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed
 
3b063ffe45377799c/superset/security/manager.py%23L322-L2772%29%0A%0A%2A%2ASuperset-side%20configuration%20checklist%3A%2A%2A%0A-%20Enable%20the%20feature%20flag%3A%20%60EMBEDDED_SUPERSET%20%3D%20True%60%20in%20%60superset_config.py%60%20or%20%60.env%60%0A-%20Set%20a%20strong%20%60GUEST_TOKEN_JWT_SECRET%60%20and%20matching%20%60GUEST_TOKEN_JWT_AUDIENCE%60%0A-%20Set%20%60GUEST_ROLE_NAME%20%3D%20%22guest_readonly%22%60%20%28or%20your%20custom%20role%20name%29%0A-%20Add%20your%20embedding%20domain%20to%20allowed%20domains%20in%20the%20dashboard%20embed%20settings%0A-%20Enable%20CORS%3A%20%60ENABLE_CORS%20%3D%20True%60%20and%20configure%20%60CORS_OPTIONS%60%0A-%20Set%20up%20Content%20Security%20Policy%20for%20iframe%20embedding%3A%0A%20%20%60%60%60python%0A%20%20TALISMAN_ENABLED%20%3D%20True%0A%20%20TALISMAN_CONFIG%20%3D%20%7B%0A%20%20%20%20%20%20%22content_security_policy%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%22frame-ancestors%22%3A%20%5B%22https%3A//your-embedding-domain.com%22%
 
5D%2C%0A%20%20%20%20%20%20%7D%0A%20%20%7D%0A%20%20%60%60%60%0A-%20Restart%20Superset%20after%20config%20changes%0A%5BReference%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/docs/docs/configuration/networking-settings.mdx%23L19-L85%29%0A%0A%2A%2ACommon%20mistakes%20and%20troubleshooting%3A%2A%2A%0A-%20Guest%20token%20missing%20required%20claims%20%28%60user%60%2C%20%60resources%60%2C%20%60rls_rules%60%2C%20%60type%3A%20guest%60%29%0A-%20Dashboard%20ID%20not%20included%20in%20the%20guest%20token%20or%20in%20chart%20data%20requests%20%28causes%20403%20errors%29%0A-%20GUEST_ROLE_NAME%20not%20set%20or%20not%20matching%20your%20custom%20role%0A-%20Embedding%20domain%20not%20listed%20in%20allowed%20domains%20or%20CSP%20%60frame-ancestors%60%0A-%20CORS%20or%20X-Frame-Options%20headers%20blocking%20iframe%20embedding%0A-%20Guest%20user%20listed%20as%20chart%20owner%20%28can%20cause%20edit%20options%20to%20appear%29%0A-%20Charts%20missing%20%60query_c
 
ontext%60%20field%20%28visit%20chart%20edit%20page%20in%20Superset%20to%20populate%29%0A-%20Token%20expired%20%28%60GUEST_TOKEN_JWT_EXP_SECONDS%60%20too%20short%29%0A%5BReference%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/security/manager.py%23L322-L2772%29%0A%0AIf%20you%20hit%20errors%20like%20%22Guest%20user%20cannot%20modify%20chart%20payload%2C%22%20check%20that%20all%20charts%20have%20a%20populated%20%60query_context%60%20field%20and%20that%20your%20guest%20token%20is%20correctly%20scoped.%0A%0ALet%20me%20know%20if%20you%20need%20more%20details%20on%20any%20step%21)&nbsp;[![Join
 
Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share
 on 
X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/issues/36377)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to