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]

Reply via email to