rusackas opened a new pull request, #41397:
URL: https://github.com/apache/superset/pull/41397

   ### SUMMARY
   
   Adopts **anandraiin3/superset#23** (originally authored via the Devin AI bot 
— credit to **@anandraiin3**). This brings the fix onto current 
`apache/superset` master with the touched code re-verified against master's 
`async_query_manager`.
   
   Closes #31492 ("Getting error when using RLS filtering in Guest token when 
`GLOBAL_ASYNC_QUERIES` is enabled").
   
   When `GLOBAL_ASYNC_QUERIES` is enabled and an embedded dashboard is loaded 
with a guest token that contains `rls_rules`, every chart and filter request 
fails with `Not authorized` (HTTP 401) and the frontend surfaces:
   
   > This session has encountered an interruption, and some controls may not 
work as intended. If you are the developer of this app, please check that the 
guest token is being generated correctly.
   
   #### Root cause
   
   The async-query path identifies a client through a server-issued 
`async-token` JWT cookie, created in `validate_session` and read back in 
`parse_channel_id_from_request` for both `POST /api/v1/chart/data` (scheduling 
the celery job) and `GET /api/v1/async_event/` (polling for completion events). 
For embedded dashboards the page renders inside a third-party iframe, so the 
`async-token` cookie is unreliable: modern browsers strip it for cross-site 
contexts or never set it (depending on `SameSite`/third-party-cookie settings). 
Subsequent polling requests typically arrive without it, which makes 
`parse_channel_id_from_request` raise `AsyncQueryTokenException` → 401. The 
error surfaces most often when RLS rules are present because the per-token 
cache key prevents a sync cache-hit shortcut from masking the cookie issue.
   
   #### Fix
   
   For requests that arrive with a guest user attached 
(`security_manager.get_current_guest_user_if_guest()`), the channel id is 
derived deterministically from stable claims of the guest token (`user`, 
`resources`, `iat`, `exp`, `aud`) using HMAC-SHA256 keyed with 
`GLOBAL_ASYNC_QUERIES_JWT_SECRET`:
   
   - Removes the dependency on a third-party cookie inside the embedded iframe.
   - Yields the same channel id for the chart-data POST, the celery worker, and 
the polling endpoint, so events written to `async-events-<channel>` are 
readable by the same guest session.
   - Stays unguessable to outside callers because the digest is keyed with the 
existing JWT secret.
   - Leaves the cookie path completely untouched for non-guest (regular) users.
   
   `validate_session` also short-circuits for guest users so it does not 
pointlessly issue an `async-token` cookie that would either fail to be set or 
never be sent back.
   
   Files changed:
   - `superset/async_events/async_query_manager.py` — new 
`get_guest_user_channel_id` helper; `parse_channel_id_from_request` and 
`validate_session` branch on `get_current_guest_user_if_guest()`.
   - `tests/unit_tests/async_events/async_query_manager_tests.py` — guest-user 
fixture mirrors the realistic guest-token payload from the bug report (RLS 
rules, `iat`/`exp`/`aud`/`type`); three new tests cover the new code path.
   
   #### Security note (reviewer aid)
   
   The channel id is the sole authz boundary for `GET /api/v1/async_event/`. 
The HMAC is keyed with the same `GLOBAL_ASYNC_QUERIES_JWT_SECRET` that protects 
the cookie JWT, so the derived channel is equally unguessable. The guest token 
signature/expiry is already validated before this code runs, and a guest can 
only derive their own channel (channel scope == token scope). No privilege 
escalation found.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A — backend-only change. The user-visible effect is that embedded 
dashboards with `rls_rules` and `GLOBAL_ASYNC_QUERIES=True` no longer return 
401 on chart and filter APIs.
   
   ### TESTING INSTRUCTIONS
   
   Automated:
   
   ```bash
   pytest tests/unit_tests/async_events/async_query_manager_tests.py -v
   ```
   
   The new tests `test_parse_channel_id_from_request_as_guest_user_no_cookie`, 
`test_parse_channel_id_from_request_as_guest_user_is_deterministic`, and 
`test_parse_channel_id_from_request_as_guest_user_differs_per_token` cover the 
regression directly. The pre-existing guest-token tests continue to pass and 
now exercise a guest-token payload that matches the one in the issue.
   
   Manual reproduction (matches the issue):
   
   1. Set `FEATURE_FLAGS = {"EMBEDDED_SUPERSET": True, "GLOBAL_ASYNC_QUERIES": 
True}` and configure the celery worker + Redis as documented.
   2. Mint a guest token whose payload includes `rls_rules` (e.g. `[{"clause": 
"\"STATEID\" = 3"}]`) for an embedded dashboard.
   3. Load the dashboard in an iframe on a different origin from Superset.
   4. **Before this PR**: every `POST /api/v1/chart/data` and `GET 
/api/v1/async_event/` returns 401 with `Not authorized`, and the embedded SDK 
surfaces the "session has encountered an interruption" toast.
   5. **After this PR**: chart-data requests return 202 with a job id, the 
polling endpoint streams completion events, and the dashboard renders normally 
with the RLS predicate applied.
   
   ### ADDITIONAL INFORMATION
   
   - [x] Has associated issue: closes #31492
   - [x] Required feature flags: `EMBEDDED_SUPERSET`, `GLOBAL_ASYNC_QUERIES` 
(existing flags; no new flags introduced)
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API
   
   ---
   
   Adopted from anandraiin3/superset#23, originally authored via the Devin AI 
bot. Credit to **@anandraiin3**.
   


-- 
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