Skip to content

feat: introduce Subject model and entity editors/viewers#38831

Merged
villebro merged 109 commits into
apache:masterfrom
villebro:villebro/subject
Jul 8, 2026
Merged

feat: introduce Subject model and entity editors/viewers#38831
villebro merged 109 commits into
apache:masterfrom
villebro:villebro/subject

Conversation

@villebro

@villebro villebro commented Mar 24, 2026

Copy link
Copy Markdown
Member

SUMMARY

This PR introduces a new Subject model, which can represent a User, Group, or Role, and replaces owner-based access management with subject-based editors. Dashboards, charts, datasets, and alerts/reports now use editors instead of owners.

In addition, a new feature flag ENABLE_VIEWERS introduces subject-based viewers for dashboards and charts. Viewers replace the previous DASHBOARD_RBAC model. For backwards compatibility, dashboards and charts with no assigned viewers keep the existing implicit dataset-permission visibility model. This means existing resources do not need viewer backfills immediately: users who can access the underlying datasets can continue to see published dashboards that use those datasets and charts backed by those datasets. Explicit Viewers are the intended access model going forward, and the implicit fallback can be considered for deprecation and removal in a later major version. A new config flag, VIEWER_PROMISCUOUS_MODE, controls whether assigned viewers can bypass regular datasource RBAC when rendering data, matching the behavior previously provided by DASHBOARD_RBAC.

RLS rules now use Subjects instead of Roles, and the RLS list view can be filtered by Subject. Subject picker normalization is centralized so resource APIs can keep returning API-shaped Subjects while form controls consistently work with picker-shaped values and submit numeric subject IDs.

This is a breaking change. The legacy owners, dashboard roles, RLS roles, and DASHBOARD_RBAC API/config semantics are removed in favor of editors, viewers, and subjects.

Motivation

The previous access model tied ownership and edit permissions directly to individual users via owners. DASHBOARD_RBAC was a step in the right direction because it recognized that dashboard visibility needs to be assignable to more than individual users, but it was implemented before Groups were available in Superset. As a result, it used Roles as the assignment target and lived as a separate, dashboard-only access system.

The better abstraction is to model resource assignments as Subjects. For new assignments, the intended default is Users and Groups: Users cover direct exceptions, and Groups cover organizational membership. Roles should stay focused on capability grants (for example, which API actions or permissions a principal has), not resource membership. This keeps permission bundles separate from data-access assignments.

For backwards compatibility, Roles are still supported as a Subject type. This preserves migration paths for existing RLS role assignments and DASHBOARD_RBAC deployments: persisted Role subject assignments continue to work even though Roles are no longer shown by default as selectable values when updating subject lists. Operators can expose Roles in subject pickers globally or per entity when needed. We may reconsider fully removing Role subjects in a later major version, but removing that compatibility layer is outside the scope of this PR.

This PR unifies the legacy concepts into a single subject model where editors can modify resources and viewers can access dashboards/charts. Subjects can be users, groups, or compatibility role subjects.

Data Model

A new subjects table stores unified references to FAB users, roles, and groups:

Field Description
uuid Stable UUID identifier
label Primary display name, for example Alice Smith, Alpha, or Data Engineering
secondary_label Secondary detail, such as email for users or group name for groups
active Whether the subject is active
extra_search Additional indexed search text
type 1=User, 2=Role, 3=Group
user_id / role_id / group_id FK to the source FAB model

Junction tables link subjects to resources:

Resource Editor table Viewer/subject table
Dashboards dashboard_editors dashboard_viewers
Charts chart_editors chart_viewers
Datasets sqlatable_editors n/a
Alerts & Reports report_schedule_editors n/a
Row Level Security n/a rls_filter_subjects

An explicit subjects table is used to keep related-object queries fast and avoid repeatedly querying across user, role, and group tables.

Legacy Table Removal

The migration drops the following legacy junction tables after seeding the new subject-based tables:

Dropped table Seeded into
dashboard_user dashboard_editors as user-type subjects
slice_user chart_editors as user-type subjects
sqlatable_user sqlatable_editors as user-type subjects
report_schedule_user report_schedule_editors as user-type subjects
dashboard_roles dashboard_viewers as role-type subjects
rls_filter_roles rls_filter_subjects as role-type subjects

The migration also renames owner tags from owner:* / owner to editor:* / editor.

On downgrade, the legacy tables are recreated and repopulated from user-type editors and role-type viewers/subjects.

Breaking API and Behavior Changes

  • Owners are removed from the API surface: API clients should send and read editors instead of owners.
  • Dashboard roles are removed: Dashboard visibility should use viewers when ENABLE_VIEWERS is enabled. Dashboards/charts with no viewers continue to use the implicit dataset-access visibility model for backwards compatibility.
  • RLS roles are removed: Row Level Security rules should use subjects instead of roles.
  • DASHBOARD_RBAC is replaced: Viewer-based dashboard/chart access is controlled by ENABLE_VIEWERS and VIEWER_PROMISCUOUS_MODE.
  • EXTRA_OWNERS_RESOLVER is replaced: Custom dynamic ownership hooks should migrate to EXTRA_EDITORS_RESOLVER, returning editor Subjects, subject IDs, or dicts with an id key. API responses expose these dynamic assignments as extra_editors instead of extra_owners.
  • Executor owner types are renamed: CREATOR_OWNER, MODIFIER_OWNER, and OWNER are replaced by CREATOR_EDITOR, MODIFIER_EDITOR, and EDITOR.
  • Editor executors resolve subject editors: The editor executor prefers modifier/creator user editors when available, then falls back to a deterministic physical user from direct user, role, or group editor subjects.
  • MCP tools use editor semantics: MCP dataset/chart/dashboard APIs have been updated to use editors instead of owners. Viewer management is intentionally not exposed in MCP yet.

Feature Flags

Flag Purpose
ENABLE_VIEWERS Gates dashboard/chart viewer pickers, viewer list columns, and viewer-based access filtering. Dashboards/charts with no viewers fall back to dataset-based visibility. Editors are always used as the edit-permission model.

New config flags

Flag Purpose
VIEWER_PROMISCUOUS_MODE When enabled with ENABLE_VIEWERS, viewers can access dashboards/charts without explicit datasource permissions, mirroring the previous DASHBOARD_RBAC behavior
SUBJECTS_RELATED_TYPES Global default list controlling which subject types appear in pickers; defaults to Users + Groups
SUBJECTS_RELATED_TYPES_DASHBOARDS Per-entity override for dashboard editor/viewer pickers
SUBJECTS_RELATED_TYPES_CHARTS Per-entity override for chart editor/viewer pickers
SUBJECTS_RELATED_TYPES_RLS Per-entity override for RLS subject pickers; can expose Roles for RLS while other pickers keep the global default
SUBJECTS_RELATED_TYPES_ALERT_REPORTS Per-entity override for alert/report editor pickers
EXTRA_RELATED_QUERY_FILTERS Extended with group support alongside existing user/role filtering hooks
EXTRA_EDITORS_RESOLVER Replaces EXTRA_OWNERS_RESOLVER for dynamic editor subject assignments and editorship checks

Subject pickers default to Users + Groups so roles can remain focused on capability grants, while resource-specific assignments use identity and organizational membership. Roles are still supported for backwards compatibility with existing RLS and DASHBOARD_RBAC usage. Existing Role subject assignments remain effective, but Roles are hidden from dropdown values unless they are re-enabled globally or per entity. Removing Role subjects entirely can be considered in a later major version.

Viewer adoption is also intentionally incremental. Enabling ENABLE_VIEWERS does not require backfilling viewers onto every existing dashboard or chart: resources with an empty viewer list keep the existing implicit dataset-access visibility behavior. Assigning at least one viewer subject opts that resource into explicit viewer access for non-editors. Unless VIEWER_PROMISCUOUS_MODE is enabled, assigned viewers still need normal datasource permissions to render the underlying data. The long-term direction is to use explicit Viewers for resource visibility; deprecating and removing the implicit fallback can be considered in a later major version.

Documentation

  • UPDATING.md: Documents the breaking API/config changes.
  • Alerts & Reports docs: Updated executor descriptions to reference user-type editors instead of owners.
  • Caching docs: Updated cache warmup executor documentation for ExecutorType.EDITOR.
  • Security/admin docs: Updated ownership terminology to editor/viewer/subject terminology.
  • Translations: Updated translation catalogs for the new editor/viewer/subject labels and help text.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

With this change, the dashboard, chart, and dataset list views have Editors instead of Owners. The new SubjectPile component displays user, role, and group subjects with distinct avatar shapes (round for Users, rounded square for Groups, octagon for Roles):

image

When the feature flag ENABLE_VIEWERS is enabled, a Viewers column appears on Dashboard and Chart list views:

image

The Editors and Viewers sections appear on the Access tab in dashboard/chart properties:

image

The Subject dropdown supports Users and Groups by default, and can also expose Roles when configured for backwards-compatible workflows:

image

When a user has viewer access to a dashboard, directly or through a Role/Group, but VIEWER_PROMISCUOUS_MODE is not enabled and they do not have datasource access, they will still see the datasource access error:

image

When VIEWER_PROMISCUOUS_MODE = True, the same viewer can render all charts on the dashboard, even without separate datasource permissions:

image

Row Level Security now uses Subjects, so filters can be assigned to Users, Roles, or Groups (notice that even if by default we don't expose Roles in Subject selectors, the Roles that were assigned to a RLS filter before this feature still appear in the dropdown):

image image

Alerts & Reports also use subject-based Editors:

image

TESTING INSTRUCTIONS

  1. Run migration: superset db upgrade
  2. Verify subjects were created: SELECT type, COUNT(*) FROM subjects GROUP BY type
  3. Verify legacy owner/role junction tables were removed and subject junction tables were populated
  4. Verify owner tags were renamed to editor tags
  5. Dashboard properties modal -> Access section shows Editors, and Viewers when ENABLE_VIEWERS is enabled
  6. Add/remove dashboard editors using user, role, and group subjects -> save -> verify persistence
  7. Non-editor cannot edit a dashboard; Admin still can
  8. Chart properties modal -> Editors picker is present and persists user/role/group subjects
  9. Dataset list and dataset edit flows -> Editors replace Owners
  10. Explore Save modal -> Only dashboards the user can edit appear in the dashboard picker
  11. Enable ENABLE_VIEWERS -> viewer-only users can see published dashboards/charts but cannot edit them
  12. With VIEWER_PROMISCUOUS_MODE = False, verify viewer access still requires datasource permissions
  13. With VIEWER_PROMISCUOUS_MODE = True, verify viewer access can render dashboards/charts without separate datasource permissions
  14. With ENABLE_VIEWERS = True, verify dashboards/charts with no viewers still fall back to dataset-based visibility
  15. Guest token access -> verify editors/viewers are stripped from API responses
  16. RLS with subjects:
    • Create RLS rule via UI/API using subjects
    • Assign rule to a user subject -> verify filter applies for that user
    • Assign rule to a role subject -> verify filter applies for users with that role
    • Assign rule to a group subject -> verify filter applies for users in that group
    • Base filter type: verify non-matching subjects get the base filter applied
    • RLS list view -> filter rules by Subject and verify the list query uses the subjects relation
  17. Alerts & Reports:
    • Add/remove editor subjects
    • Verify executor behavior with EDITOR, CREATOR_EDITOR, and MODIFIER_EDITOR
  18. MCP tools:
    • Verify dataset/chart/dashboard APIs use editor terminology
    • Verify stale owner fields are not exposed as active API semantics
    • Verify viewers are not exposed through MCP tooling yet
  19. Dynamic editor resolver:
    • Configure EXTRA_EDITORS_RESOLVER
    • Verify returned subject IDs grant edit access
    • Verify chart/dashboard GET responses expose extra_editors
  20. Subject sync from UI:
    • Edit a user's first/last name -> verify the corresponding Subject label updates
    • Create a new user -> verify a Subject row is created
    • Rename a role -> verify the Subject label updates
    • Create/rename a group -> verify Subject sync
    • Delete a user/role/group -> verify the Subject row is removed
  21. Per-entity subject type filtering:
    • Verify default subject pickers show users + groups
    • Set SUBJECTS_RELATED_TYPES = [SubjectType.USER] and SUBJECTS_RELATED_TYPES_RLS = [SubjectType.USER, SubjectType.GROUP, SubjectType.ROLE]
    • Dashboard editors picker shows only users
    • RLS subjects picker shows users, groups, and roles
    • Set SUBJECTS_RELATED_TYPES = [SubjectType.USER, SubjectType.ROLE, SubjectType.GROUP] -> all subject types appear everywhere
  22. Optional downgrade check: superset db downgrade and verify legacy tables are recreated from editor/viewer/subject data

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags: ENABLE_VIEWERS for viewer UI/access behavior
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration supports rollback
    • Migration is backwards-compatible: this PR intentionally introduces breaking API/config changes
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@github-actions github-actions Bot added risk:db-migration PRs that require a DB migration api Related to the REST API packages and removed size/XXL labels Mar 24, 2026
@codecov

codecov Bot commented Mar 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.16141% with 354 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.70%. Comparing base (01e872c) to head (413eea4).

Files with missing lines Patch % Lines
superset/cli/sync_subjects.py 0.00% 49 Missing ⚠️
superset/daos/group.py 0.00% 30 Missing ⚠️
superset/daos/role.py 0.00% 26 Missing ⚠️
...uperset/mcp_service/dataset/tool/create_dataset.py 13.33% 26 Missing ⚠️
superset/commands/export/assets.py 48.57% 18 Missing ⚠️
superset/dashboards/filters.py 67.56% 10 Missing and 2 partials ⚠️
superset/commands/chart/importers/v1/utils.py 57.69% 9 Missing and 2 partials ⚠️
superset/commands/utils.py 81.13% 7 Missing and 3 partials ⚠️
superset/daos/dashboard.py 47.05% 4 Missing and 5 partials ⚠️
...tend/src/features/subjects/SubjectPicker/index.tsx 50.00% 8 Missing ⚠️
... and 55 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #38831      +/-   ##
==========================================
+ Coverage   64.10%   64.70%   +0.59%     
==========================================
  Files        2702     2717      +15     
  Lines      150219   151718    +1499     
  Branches    34591    34751     +160     
==========================================
+ Hits        96303    98170    +1867     
+ Misses      52130    51722     -408     
- Partials     1786     1826      +40     
Flag Coverage Δ
hive 39.04% <31.41%> (-0.02%) ⬇️
javascript 69.78% <83.17%> (-0.02%) ⬇️
mysql 57.48% <57.09%> (-0.10%) ⬇️
postgres 57.54% <57.09%> (-0.10%) ⬇️
presto 40.55% <31.57%> (-0.03%) ⬇️
python 58.94% <57.09%> (+1.10%) ⬆️
sqlite 57.13% <57.09%> (-0.09%) ⬇️
superset-extensions-cli 90.59% <ø> (?)
unit 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@netlify

netlify Bot commented Mar 24, 2026

Copy link
Copy Markdown

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 413eea4
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6a4e84ce93fff300086acebc
😎 Deploy Preview https://deploy-preview-38831--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.

@github-actions github-actions Bot added the doc Namespace | Anything related to documentation label Mar 25, 2026
@villebro
villebro force-pushed the villebro/subject branch 18 times, most recently from 9f26ac3 to 5ddcf81 Compare April 1, 2026 22:35
Comment thread superset-frontend/src/features/reports/ReportModal/index.tsx Outdated

@EnxDev EnxDev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few non-blocking follow-ups that might be worth considering:

  1. superset/subjects/utils.py:101 — The embedded guest branch in get_current_user_subject_ids doesn't seem to be covered by tests. It might be worth adding one to avoid regressions.
  2. Migration UUID backfill — The backfill performs one UPDATE per subject. Would batching these updates improve performance on larger installations?
  3. UPDATING.md — Since viewers are now always seeded from dashboard_roles, it may be worth documenting the upgrade impact for installations with stale dashboard_roles data.
  4. superset/dashboards/schemas.py:590 — Old dashboard bundles silently drop roles on import. Would it make sense to map them to viewers or at least emit a warning?

Nits

  • Remove _apply_legacy if it's no longer used.
  • The ENABLE_VIEWERS branches in reports/filters.py appear identical—could they be simplified?
  • _get_user_subject_id swallows all exceptions. Would logging a warning help with debugging?
  • ReportModal.userId appears unused and could potentially be removed.

@villebro

villebro commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

A few non-blocking follow-ups that might be worth considering:

  1. superset/subjects/utils.py:101 — The embedded guest branch in get_current_user_subject_ids doesn't seem to be covered by tests. It might be worth adding one to avoid regressions.
  2. Migration UUID backfill — The backfill performs one UPDATE per subject. Would batching these updates improve performance on larger installations?
  3. UPDATING.md — Since viewers are now always seeded from dashboard_roles, it may be worth documenting the upgrade impact for installations with stale dashboard_roles data.
  4. superset/dashboards/schemas.py:590 — Old dashboard bundles silently drop roles on import. Would it make sense to map them to viewers or at least emit a warning?

Nits

  • Remove _apply_legacy if it's no longer used.
  • The ENABLE_VIEWERS branches in reports/filters.py appear identical—could they be simplified?
  • _get_user_subject_id swallows all exceptions. Would logging a warning help with debugging?
  • ReportModal.userId appears unused and could potentially be removed.

Thanks for the new review pass! I addressed the other bits, but I'd like to push back on 4: imports/exports are not expected to be compatible across major versions, and when this feature ships in 7.0, exports will not contain dashboard roles, making the role-to-viewer compatibility mapping a no-op.

@EnxDev EnxDev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested Ville's branch, and everything seems to be working as expected.
Thanks for this significant contribution, @villebro great work!

@rusackas rusackas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codeowner review granted

@bito-code-review

Copy link
Copy Markdown
Contributor

Bito Automatic Review Skipped – PR Already Merged

Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.
No action is needed if you didn't intend to review it. To get a review, you can type /review in a comment and save it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Related to the REST API authentication:RBAC Related to RBAC change:backend Requires changing the backend change:frontend Requires changing the frontend doc Namespace | Anything related to documentation i18n:brazilian i18n:czech i18n:dutch i18n:french Translation related to French language i18n:italian Translation related to Italian language i18n:japanese Translation related to Japanese language i18n:latvian i18n:persian i18n:russian Translation related to Russian language i18n:slovak i18n:spanish Translation related to Spanish language i18n:ukrainian i18n Namespace | Anything related to localization packages plugins review:draft risk:breaking-change Issues or PRs that will introduce breaking changes risk:db-migration PRs that require a DB migration size/XXL

Projects

Status: Lazy Consensus Reached

Development

Successfully merging this pull request may close these issues.

5 participants