Skip to content

fix(SIP): Session/token lifecycle and extension supply-chain hardening (proposal)#40674

Draft
rusackas wants to merge 1 commit into
masterfrom
sip/auth-session-supply-chain-hardening
Draft

fix(SIP): Session/token lifecycle and extension supply-chain hardening (proposal)#40674
rusackas wants to merge 1 commit into
masterfrom
sip/auth-session-supply-chain-hardening

Conversation

@rusackas
Copy link
Copy Markdown
Member

@rusackas rusackas commented Jun 2, 2026

Draft / hold:sip! — this is a proposal document, not an implementation. Opening it as a draft PR so the SIP can be discussed inline.

SUMMARY

Adds docs/sip/auth-session-and-extension-supply-chain-hardening.md, a SIP proposal collecting the security-review items that are not safely shippable as isolated, untested PRs (each needs a behavior-sensitive change, a schema migration, or cross-component coordination):

  • A1 — Session fixation: regenerate the session on login (matters mainly for server-side-session deployments; signed client-cookie sessions already mitigate it).
  • A2 — Session termination on disable/delete: a backend-agnostic per-user "invalidation epoch" that forces logout of outstanding sessions.
  • A3 — Guest-token revocation: per-embedded-dashboard revoked_before timestamp checked against the token iat.
  • Part B — Extension supply chain: pluggable advisory/vuln-DB checks + version policy (the static EXTENSION_BLOCKLIST already shipped).

Each section states the gap, a proposed design, compatibility considerations, and rejected alternatives, plus a suggested phasing.

TESTING INSTRUCTIONS

N/A — documentation only.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API
  • Removes existing feature or API

🤖 Generated with Claude Code

@github-actions github-actions Bot added the doc Namespace | Anything related to documentation label Jun 2, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 2, 2026

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 6fd6557
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a21ad19fd65960008996162
😎 Deploy Preview https://deploy-preview-40674--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@rusackas rusackas moved this from Needs Review to Needs Follow-Up Work in Superset Review Help Wanted Jun 2, 2026
@rusackas rusackas changed the title [SIP] Session/token lifecycle and extension supply-chain hardening (proposal) fix(SIP): Session/token lifecycle and extension supply-chain hardening (proposal) Jun 2, 2026
@sha174n sha174n added the merge-if-green If approved and tests are green, please go ahead and merge it for me label Jun 2, 2026
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Implements Part A3 of the session/token-lifecycle SIP (#40674): granular,
per-embedded-dashboard guest-token revocation that complements the global
revocation mechanism.

- `embedded_dashboards.guest_token_revoked_before` (migration) records the
  revocation instant for one embedded dashboard.
- `get_guest_user_from_request` rejects a guest token whose `iat` predates the
  `guest_token_revoked_before` of any dashboard resource it references (UTC-safe
  comparison). Tokens issued afterwards, and dashboards never revoked (NULL),
  are unaffected.
- `POST /api/v1/dashboard/<id_or_slug>/embedded/revoke` (gated by the existing
  `can_set_embedded` permission) stamps the timestamp via
  `EmbeddedDashboardDAO.revoke_guest_tokens`.

Guest tokens already carry `iat`, so no token-format change is needed.
Validated end-to-end against a local Docker stack (token valid -> revoke ->
rejected -> new token valid; revoke endpoint returns 200) plus integration
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Implements Part A3 of the session/token-lifecycle SIP (#40674): granular,
per-embedded-dashboard guest-token revocation that complements the global
revocation mechanism.

- `embedded_dashboards.guest_token_revoked_before` (migration) records the
  revocation instant for one embedded dashboard.
- `get_guest_user_from_request` rejects a guest token whose `iat` predates the
  `guest_token_revoked_before` of any dashboard resource it references (UTC-safe
  comparison). Tokens issued afterwards, and dashboards never revoked (NULL),
  are unaffected.
- `POST /api/v1/dashboard/<id_or_slug>/embedded/revoke` (gated by the existing
  `can_set_embedded` permission) stamps the timestamp via
  `EmbeddedDashboardDAO.revoke_guest_tokens`.

Guest tokens already carry `iat`, so no token-format change is needed.
Validated end-to-end against a local Docker stack (token valid -> revoke ->
rejected -> new token valid; revoke endpoint returns 200) plus integration
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Implements Part A3 of the session/token-lifecycle SIP (#40674): granular,
per-embedded-dashboard guest-token revocation that complements the global
revocation mechanism.

- `embedded_dashboards.guest_token_revoked_before` (migration) records the
  revocation instant for one embedded dashboard.
- `get_guest_user_from_request` rejects a guest token whose `iat` predates the
  `guest_token_revoked_before` of any dashboard resource it references (UTC-safe
  comparison). Tokens issued afterwards, and dashboards never revoked (NULL),
  are unaffected.
- `POST /api/v1/dashboard/<id_or_slug>/embedded/revoke` (gated by the existing
  `can_set_embedded` permission) stamps the timestamp via
  `EmbeddedDashboardDAO.revoke_guest_tokens`.

Guest tokens already carry `iat`, so no token-format change is needed.
Validated end-to-end against a local Docker stack (token valid -> revoke ->
rejected -> new token valid; revoke endpoint returns 200) plus integration
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Implements Part A3 of the session/token-lifecycle SIP (#40674): granular,
per-embedded-dashboard guest-token revocation that complements the global
revocation mechanism.

- `embedded_dashboards.guest_token_revoked_before` (migration) records the
  revocation instant for one embedded dashboard.
- `get_guest_user_from_request` rejects a guest token whose `iat` predates the
  `guest_token_revoked_before` of any dashboard resource it references (UTC-safe
  comparison). Tokens issued afterwards, and dashboards never revoked (NULL),
  are unaffected.
- `POST /api/v1/dashboard/<id_or_slug>/embedded/revoke` (gated by the existing
  `can_set_embedded` permission) stamps the timestamp via
  `EmbeddedDashboardDAO.revoke_guest_tokens`.

Guest tokens already carry `iat`, so no token-format change is needed.
Validated end-to-end against a local Docker stack (token valid -> revoke ->
rejected -> new token valid; revoke endpoint returns 200) plus integration
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Implements Part A3 of the session/token-lifecycle SIP (#40674): granular,
per-embedded-dashboard guest-token revocation that complements the global
revocation mechanism.

- `embedded_dashboards.guest_token_revoked_before` (migration) records the
  revocation instant for one embedded dashboard.
- `get_guest_user_from_request` rejects a guest token whose `iat` predates the
  `guest_token_revoked_before` of any dashboard resource it references (UTC-safe
  comparison). Tokens issued afterwards, and dashboards never revoked (NULL),
  are unaffected.
- `POST /api/v1/dashboard/<id_or_slug>/embedded/revoke` (gated by the existing
  `can_set_embedded` permission) stamps the timestamp via
  `EmbeddedDashboardDAO.revoke_guest_tokens`.

Guest tokens already carry `iat`, so no token-format change is needed.
Validated end-to-end against a local Docker stack (token valid -> revoke ->
rejected -> new token valid; revoke endpoint returns 200) plus integration
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Completes the static supply-chain controls for Part B of the security SIP
(#40674), alongside the EXTENSION_DENYLIST in this PR.

- EXTENSION_VERSION_POLICY maps an extension id to a minimum allowed version;
  releases below it are refused (PEP 440 comparison, fail-closed on unparseable
  versions).
- Consolidate the denylist + version checks into get_extension_rejection_reason,
  removing the duplicated rejection blocks across the two load paths and logging
  a single, specific reason.
- Add UPDATING.md notes for both controls.

The pluggable advisory/vuln-DB provider remains a separate follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 3, 2026
Completes the static supply-chain controls for Part B of the security SIP
(#40674), alongside the EXTENSION_DENYLIST in this PR.

- EXTENSION_VERSION_POLICY maps an extension id to a minimum allowed version;
  releases below it are refused (PEP 440 comparison, fail-closed on unparseable
  versions).
- Consolidate the denylist + version checks into get_extension_rejection_reason,
  removing the duplicated rejection blocks across the two load paths and logging
  a single, specific reason.
- Add UPDATING.md notes for both controls.

The pluggable advisory/vuln-DB provider remains a separate follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Proposal collecting the security-review items that are not safely shippable as
isolated PRs: session regeneration on login (A1), session termination on
account disable/delete via an invalidation epoch (A2), guest-token revocation
(A3), and extension supply-chain advisory checks (Part B). Each section gives a
proposed design, compatibility notes, and rejected alternatives.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rusackas rusackas force-pushed the sip/auth-session-supply-chain-hardening branch from d67b849 to 6fd6557 Compare June 4, 2026 16:51
rusackas pushed a commit that referenced this pull request Jun 4, 2026
Implements Part A2 of the session/token-lifecycle SIP (#40674): a
backend-agnostic per-user invalidation epoch.

- `UserAttribute.sessions_invalidated_at` (migration) records when a user's
  sessions were invalidated.
- Login stamps `session["_login_at"]`; a `before_request` hook forces logout of
  any session that predates the user's epoch, then lets the request continue as
  anonymous so each route responds correctly for its type (401 for the REST API,
  redirect-to-login for HTML views).
- A SQLAlchemy `after_update` listener stamps the epoch when `active` flips to
  False, so it fires regardless of the disable path (admin UI, REST API, CLI),
  for both client-side cookie and server-side session backends.

Inert for users that were never disabled (NULL epoch) — backwards compatible by
default. Comparison treats the naive UTC column correctly. Validated end-to-end
against a local Docker stack (login -> disable -> forced 401) plus unit and
integration tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Jun 4, 2026
Completes the static supply-chain controls for Part B of the security SIP
(#40674), alongside the EXTENSION_DENYLIST in this PR.

- EXTENSION_VERSION_POLICY maps an extension id to a minimum allowed version;
  releases below it are refused (PEP 440 comparison, fail-closed on unparseable
  versions).
- Consolidate the denylist + version checks into get_extension_rejection_reason,
  removing the duplicated rejection blocks across the two load paths and logging
  a single, specific reason.
- Add UPDATING.md notes for both controls.

The pluggable advisory/vuln-DB provider remains a separate follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@rusackas rusackas removed the merge-if-green If approved and tests are green, please go ahead and merge it for me label Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc Namespace | Anything related to documentation hold:sip! preset-io review:draft size/L

Projects

Status: Needs Follow-Up Work

Development

Successfully merging this pull request may close these issues.

4 participants