aminghadersohi opened a new pull request, #36933:
URL: https://github.com/apache/superset/pull/36933
## **User description**
### SUMMARY
Add embeddable charts with guest token authentication, accessible via both:
1. **MCP Tool** (`get_embeddable_chart`) - For AI agents to create charts
programmatically
2. **UI Button** ("Embed code" in Share menu) - For users to embed charts
from Explore/Dashboard
**Key Features:**
- **Ephemeral Charts**: Uses permalink system with TTL (no database
persistence needed)
- **Guest Token Auth**: New `CHART_PERMALINK` resource type for secure
embedding
- **UI Integration**: "Embed code" in chart Share menu (Explore page and
Dashboard)
- **MCP Integration**: Tool for AI agents to generate embeddable charts
**Recent Improvements:**
- ✅ Fixed initialization flash in embed modal (smooth loading UX)
- ✅ Improved datasource access validation (proper security checks)
- ✅ Enhanced error handling with specific user-friendly messages
- ✅ Rebased on latest apache/superset master
---
### CONFIGURATION
#### Required Feature Flag
```python
FEATURE_FLAGS = {
"EMBEDDED_SUPERSET": True, # Required - enables guest token
authentication
}
```
#### Guest Token Settings
| Config | Default | Description |
|--------|---------|-------------|
| `GUEST_TOKEN_JWT_SECRET` | `"test-guest-secret-change-me"` | **Change in
production!** Generate with `openssl rand -base64 42` |
| `GUEST_TOKEN_JWT_EXP_SECONDS` | `300` (5 min) | Token validity duration.
Set >= expected embed session length |
| `GUEST_TOKEN_JWT_ALGO` | `"HS256"` | JWT signing algorithm |
| `GUEST_TOKEN_JWT_AUDIENCE` | `None` | Optional JWT audience claim |
| `GUEST_TOKEN_HEADER_NAME` | `"X-GuestToken"` | HTTP header name for token |
#### Feature Flags
| Flag | Default | Description |
|------|---------|-------------|
| `EMBEDDABLE_CHARTS` | `True` | Show "Embed code" option in Share menu |
#### Iframe Embedding (Development)
For local development, you may need to allow iframe embedding:
```python
# Allow embedding in iframes (disable X-Frame-Options)
HTTP_HEADERS = {"X-Frame-Options": "ALLOWALL"}
# Disable Talisman CSP (development only!)
TALISMAN_ENABLED = False
```
#### Example Production Config
```python
FEATURE_FLAGS = {
"EMBEDDED_SUPERSET": True,
}
# Generate a secure secret for production
GUEST_TOKEN_JWT_SECRET = "your-secure-secret-here"
GUEST_TOKEN_JWT_EXP_SECONDS = 3600 # 1 hour
```
---
### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
**New "Embed chart" menu option:**
<img width="520" height="356" alt="Screenshot 2026-01-08 at 7 11 27 PM"
src="https://github.com/user-attachments/assets/af109f4d-2632-496a-b939-960227f39636"
/>
<img width="628" height="489" alt="Screenshot 2026-01-08 at 7 11 41 PM"
src="https://github.com/user-attachments/assets/9929fcd9-8df8-4927-9d2b-e3666dac74fd"
/>
<img width="618" height="372" alt="Screenshot 2026-01-08 at 7 12 56 PM"
src="https://github.com/user-attachments/assets/f43805fe-0ae7-44a3-8722-46a7ad93b129"
/>
<img width="430" height="336" alt="Screenshot 2026-01-08 at 7 13 05 PM"
src="https://github.com/user-attachments/assets/95e9fc24-b219-4d80-8b4a-4c0b9826d9ce"
/>
<img width="246" height="504" alt="Screenshot 2026-01-08 at 7 33 23 PM"
src="https://github.com/user-attachments/assets/8708f667-47c9-4610-9db4-50d55e7dddbe"
/>
<img width="1706" height="746" alt="Screenshot 2026-01-08 at 7 33 46 PM"
src="https://github.com/user-attachments/assets/ed3d0249-14c1-42e1-b5d2-a70952333151"
/>
**Embedded chart rendering:**
<img width="1072" height="709" alt="Embed chart menu option"
src="https://github.com/user-attachments/assets/f9ee180a-afca-441a-9e49-88f4c293620b"
/>
<img width="1079" height="742" alt="Embedded chart in external app"
src="https://github.com/user-attachments/assets/6066674c-5e84-4484-ab1e-46881b0ff28e"
/>
### TESTING INSTRUCTIONS
#### Testing via UI
1. Enable `EMBEDDED_SUPERSET` feature flag in `superset_config.py`
2. Open a chart in Explore or a dashboard
3. Click the Share menu → "Embed code"
4. Copy the generated code and paste into an HTML file
5. Open the HTML file in a browser to see the embedded chart
#### Testing via MCP (for AI Agents)
**1. Create embeddable chart:**
```json
// Use get_embeddable_chart MCP tool
{
"datasource_id": 22,
"viz_type": "echarts_timeseries_bar",
"form_data": {
"x_axis": "genre",
"metrics": [{
"aggregate": "SUM",
"column": {"column_name": "global_sales"},
"expressionType": "SIMPLE",
"label": "Total Global Sales"
}]
},
"ttl_minutes": 60,
"height": 500
}
```
**2. Embed in HTML:**
```html
<!-- Paste iframe_html from response -->
<iframe id="chart"
src="http://localhost:9081/embedded/chart/?permalink_key=XXX"
width="100%" height="500px" frameborder="0"
data-guest-token="TOKEN"></iframe>
<script>
document.getElementById("chart").onload = function() {
this.contentWindow.postMessage(
{ type: "__embedded_comms__", guestToken: this.dataset.guestToken },
new URL(this.src).origin
);
};
</script>
```
### ADDITIONAL INFORMATION
**Architecture:**
- Uses existing permalink infrastructure (no new database tables)
- Guest tokens validated against `CHART_PERMALINK` resource type
- Compatible with Row Level Security (RLS) rules via guest token
**Security Improvements:**
- Datasource access properly validated against permalink contents
- Guest users can only access datasources explicitly granted in their token
- Referrer validation for allowed domains
**Important Notes:**
- `ttl_minutes` parameter controls **permalink** expiration
- `GUEST_TOKEN_JWT_EXP_SECONDS` controls **guest token** expiration
- Both must be set appropriately for your embed session duration
___
## **CodeAnt-AI Description**
Add embeddable chart capability with guest-token authentication and UI
controls
### What Changed
- Users can generate short-lived embeddable charts: the Explore "Embed code"
now creates an iframe URL and guest token so external apps can securely load a
chart without persisting chart state to the DB.
- Saved charts can be configured for persistent embedding: a new "Embed
chart" modal in Explore and chart header lets owners enable/disable embedding
and set allowed domains; an "Embedded Charts" admin list page shows all
configured embeds and lets admins copy UUIDs or disable embedding.
- Embedded iframe page now initializes as an isolated app that accepts a
guest token (postMessage) and fetches chart formData from a permalink to render
the chart inside the iframe.
- Backend APIs and MCP tool support: endpoints to create/get/delete/list
embedded charts and a new MCP tool to produce embeddable charts
programmatically (returns iframe URL, guest token, expiry, and ready-to-use
iframe HTML). Tests added for the MCP tool and embed code generation flows.
- Security and permissions: guest tokens are scoped to a chart permalink
resource; server validates guest tokens against permalink access. Guest role
permission checks are auto-configured when needed. New DB table to store
persistent embedded chart configs. Feature flags default off (EMBEDDABLE_CHARTS
and EMBEDDED_SUPERSET require enabling).
### Impact
`✅ Easier embedding of charts in external apps`
`✅ Clearer embed lifecycle (TTL and expiry shown)`
`✅ Admin ability to manage and revoke embed UUIDs`
<details>
<summary><strong>💡 Usage Guide</strong></summary>
### Checking Your Pull Request
Every time you make a pull request, our system automatically looks through
it. We check for security issues, mistakes in how you're setting up your
infrastructure, and common code problems. We do this to make sure your changes
are solid and won't cause any trouble later.
### Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can
easily get in touch with CodeAnt AI right here. Just type the following in a
comment on your pull request, and replace "Your question here" with whatever
you want to ask:
<pre>
<code>@codeant-ai ask: Your question here</code>
</pre>
This lets you have a chat with CodeAnt AI about your pull request, making it
easier to understand and improve your code.
#### Example
<pre>
<code>@codeant-ai ask: Can you suggest a safer alternative to storing this
secret?</code>
</pre>
### Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future
reviews. Reply directly to the specific CodeAnt AI suggestion (in the same
thread) and replace "Your feedback here" with your input:
<pre>
<code>@codeant-ai: Your feedback here</code>
</pre>
This helps CodeAnt AI learn and adapt to your team's coding style and
standards.
#### Example
<pre>
<code>@codeant-ai: Do not flag unused imports.</code>
</pre>
### Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
<pre>
<code>@codeant-ai: review</code>
</pre>
### Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at
[https://app.codeant.ai](https://app.codeant.ai). This tool helps you identify
potential issues and areas for improvement in your codebase, ensuring your
repository maintains high standards of code health.
</details>
--
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]