rusackas opened a new pull request, #40651: URL: https://github.com/apache/superset/pull/40651
> **Draft / `hold:testing`** — touches session/cookie lifetime behavior for Global Async Queries. Needs end-to-end validation before merge (see "Why draft"). ### SUMMARY The async-queries JWT (set as the `async-token` cookie, used to authenticate the async event channel and the WebSocket connection) was minted **without an `exp` claim**, so a leaked cookie granted access to the user's async event channel indefinitely (CWE-613). This adds `iat`/`exp` to the token with a configurable lifetime (`GLOBAL_ASYNC_QUERIES_JWT_EXP_SECONDS`, default 1h) and a **sliding refresh** so active sessions are never disrupted: - `validate_session` (the `after_request` handler) now reissues the cookie whenever the token is **missing, legacy (no `exp`), expired, or past the first half of its lifetime**, while **reusing the existing channel** (only minting a brand-new channel when there isn't one for the user, as before). - The cookie gets a matching `max_age`. - PyJWT validates `exp` on decode, so an expired (e.g. leaked) token is rejected by `parse_channel_id_from_request` and by the WebSocket server's verifier. Legacy tokens without `exp` are transparently upgraded on the next request, so there's no flag-day. ### WHY DRAFT (`hold:testing`) This changes cookie/session lifetime semantics for GAQ. The proactive refresh (second-half-of-lifetime) keeps active sessions valid, but there's one edge worth validating: a session left **idle beyond the full token lifetime** will have both the cookie (`max_age`) and token expired; the first request afterward re-issues the cookie via `after_request`, but if that very first request is itself an async-query submit, it could see a transient token error and need a retry. Needs validation that: - normal active navigation never surfaces a token error (expected: proactive refresh covers it); - the WebSocket transport reconnects cleanly when the token is refreshed; - the long-idle edge degrades gracefully. ### TESTING INSTRUCTIONS ``` pytest tests/unit_tests/async_events/async_query_manager_tests.py ``` New unit tests: `generate_jwt` sets `iat`/`exp` and round-trips; an expired token is rejected; `_jwt_needs_refresh` refreshes missing/legacy/expired/near-expiry tokens and keeps fresh ones. **Before merge:** exercise the full GAQ flow (polling + `ws` transport) across a token-refresh boundary. ### ADDITIONAL INFORMATION - [ ] Has associated issue: - [ ] Required feature flags: GLOBAL_ASYNC_QUERIES - [ ] Changes UI - [ ] Includes DB Migration - [ ] Introduces new feature or API - [ ] Removes existing feature or API 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- 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]
