Dataset Access Control#
Superset enforces a three-layer authorization model for datasets :
| Layer | Mechanism | Controls |
|---|---|---|
| Ownership | owners M2M on SqlaTable | Who can edit the dataset definition |
| Capability | FAB can_read/can_write PVMs on the Dataset view-menu | Who can call dataset CRUD APIs |
| Query access | Object-scoped datasource_access PVM per dataset | Who can run queries/charts against the dataset |
This article covers the ownership and query-access layers. The RBAC capability layer is documented in Role and Permission Management. Row-Level Security (SQL-level data filtering) is a separate concern.
All runtime enforcement for the query-access layer flows through SupersetSecurityManager.raise_for_access() in superset/security/manager.py.
Ownership#
SqlaTable carries an owners many-to-many relationship to FAB users via the sqlatable_user association table . Admins and dataset owners bypass all further access checks in raise_for_access — they are treated as having full query access.
Auto-assignment on creation: The CreateDatasetCommand adds the creating user to owners. During import, import_dataset() automatically appends the importing user to dataset.owners if not already present .
Ownership grants edit rights to the dataset definition and query access for the owner; it does not extend query access to other users.
datasource_access Permission#
Each dataset gets a FAB PermissionView (PVM) with the action datasource_access and a view-menu name computed by get_dataset_perm():
[{database_name}].[{dataset_name}](id:{dataset_id})
The id:{dataset_id} suffix makes the permission unique even if the table is renamed or moved .
Companion permissions#
When a dataset belongs to a schema or catalog, additional PVMs are created automatically by dataset_after_insert():
| PVM action | View-menu format |
|---|---|
schema_access | [{database}].[{schema}] or [{database}].[{catalog}].[{schema}] |
catalog_access | [{database}].[{catalog}] |
database_access | managed on the Database model |
A user with schema_access for a schema can query all datasets in that schema without explicit per-dataset grants .
Object-scoped permissions like datasource_access are never assigned to built-in roles (Admin, Alpha, Gamma, sql_lab) — they must be explicitly granted to custom roles .
PVM lifecycle (SQLAlchemy event hooks)#
PVMs are created and synchronized by event listeners on SqlaTable, delegating to SupersetSecurityManager:
| Event | Manager method | Action |
|---|---|---|
after_insert | dataset_after_insert() | Creates datasource_access + schema_access / catalog_access PVMs; writes perm, schema_perm, catalog_perm columns |
before_update | dataset_before_update() | Updates PVMs and columns when table name, schema, or database changes |
after_delete | dataset_after_delete() | Removes the datasource_access PVM |
Query-Level Access Check#
raise_for_access() is the single enforcement point for dataset query access — invoked on every chart render and query. Access is granted if any of the following conditions is true (evaluated in order) :
- Schema/higher-scope access —
can_access_schema(datasource)passes if the user holdsall_datasource_access,database_access,catalog_access, orschema_accessfor the datasource's schema. - Direct datasource PVM —
can_access("datasource_access", datasource.perm). - Ownership —
is_owner(datasource). - Dashboard bypass — if the request targets a chart on a specific dashboard, the datasource check is bypassed when either
DASHBOARD_RBACis enabled and the dashboard has roles, or the user is an embedded guest with a valid guest token .
If none applies, raise_for_access raises SupersetSecurityException with a DATASOURCE_SECURITY_ACCESS_ERROR and message: "This endpoint requires the datasource {id}, database or all_datasource_access permission" .
Boolean wrapper: can_access_datasource(datasource) wraps raise_for_access and returns True/False rather than raising.
Permission hierarchy#
all_datasource_access
└── all_database_access / database_access (per-database)
└── catalog_access (per-catalog, if supported)
└── schema_access (per-schema)
└── datasource_access (per-dataset — most restrictive)
SQL Lab and MCP: Strict Dataset Matching#
For raw SQL queries (SQL Lab and the MCP execute_sql tool), schema-level access alone is insufficient. PR #40409 introduced a force_dataset_match=True parameter to raise_for_access. When set, the referenced table must resolve to a registered Superset dataset the user can access via datasource_access; catalog_access or schema_access fallbacks are skipped .
Call sites that pass force_dataset_match=True:
- SQL Lab execution pre-flight (
superset/sqllab/validators.py) - Query result fetch and export (
superset/models/sql_lab.py) - MetaDB database+table access path (
superset/extensions/metadb.py) - MCP
execute_sqltool, aligned by PR #43998
PR #43998 updated the MCP execute_sql path to call raise_for_access(force_dataset_match=True) (passing database, SQL, catalog, schema, and template parameters) so that it matches SQL Lab's enforcement exactly. Previously, MCP only checked database-level access, allowing bypasses that SQL Lab would have blocked.
Note: Users who previously relied on
schema_accessalone for raw SQL Lab queries now need database-level access or an explicitly accessible registered dataset .
Key Source Files#
| File | Relevance |
|---|---|
superset/security/manager.py | SupersetSecurityManager: raise_for_access, can_access_datasource, can_access_schema, get_dataset_perm, dataset_after_insert, dataset_before_update, dataset_after_delete |
superset/connectors/sqla/models.py | SqlaTable: owners relationship, sqlatable_user table, get_perm(), SQLAlchemy event listeners, perm/schema_perm/catalog_perm columns |
superset/commands/dataset/create.py | Owner auto-assignment on dataset creation |
superset/commands/dataset/importers/v1/utils.py | Dataset import: ownership auto-assignment, can_write check |
superset/sqllab/validators.py | SQL Lab pre-flight: calls raise_for_access(force_dataset_match=True) |
docs/docs/security/security.mdx | Official security documentation covering roles, permissions, and datasource access |
Related articles: Access Control (dashboard/role-based access) · Role and Permission Management (FAB roles, PVMs, built-in roles)