Role and Permission Management#
Superset's role and permission system is built on Flask-AppBuilder (FAB) RBAC, extended by SupersetSecurityManager. The core abstractions are:
- Permission — an action name (e.g.
can_read,can_write,datasource_access) - ViewMenu — a resource name (e.g.
Dashboard, a specific database) - PermissionView (PVM) — a
(Permission, ViewMenu)pair stored inab_permission_view - Role — a named set of PVMs; users gain access by holding one or more roles
Four built-in roles are managed by Superset: Admin, Alpha, Gamma, and sql_lab. These are rebuilt on every superset init . Object-scoped permissions (database_access, schema_access, datasource_access) are never assigned to built-in roles — they are managed per-object via SQLAlchemy event hooks .
Scope: This article covers the schema, management APIs, and utility methods. See Permission Registration for initialization/deduplication, Access Control for runtime enforcement, and Permission Propagation for frontend propagation.
Database Schema#
Superset inherits FAB's five-table RBAC schema :
| Table | Key Columns | Purpose |
|---|---|---|
ab_permission | id, name | Action names (e.g. can_read) |
ab_view_menu | id, name | Resource names (e.g. Dashboard) |
ab_permission_view | permission_id, view_menu_id | PVM records; unique on (permission_id, view_menu_id) |
ab_permission_view_role | permission_view_id, role_id | Assigns PVMs to roles; unique on (permission_view_id, role_id) |
ab_role | id, name | Role definitions |
The unique constraints on ab_permission_view and ab_permission_view_role prevent duplicate PVMs and role assignments .
Managing Roles and Permissions#
CLI: superset init#
The superset init command is the primary way to provision built-in roles. It runs two operations in sequence:
appbuilder.add_permissions(update_perms=True)— registers all FAB view/action PVMs in the databasesecurity_manager.sync_role_definitions()— rebuilds Admin, Alpha, Gamma, and sql_lab role memberships and cleans up orphaned PVMs
There are no dedicated CLI commands for exporting or importing roles individually — CLI-level role management is exclusively via superset init .
REST API#
RoleRestAPI at GET /api/v1/security/roles/search/ lists roles with pagination and RISON-style filtering . Supported filter columns are user_ids, permission_ids, group_ids, and name. Each response object includes id, name, user_ids, permission_ids, and group_ids arrays. The endpoint requires the list_roles permission and is admin-only .
Full role CRUD is provided by the FAB-inherited SupersetRoleApi, which overrides only pre_delete() to clear item.permissions before deletion in order to satisfy database constraints.
UI#
RolesListView at /roles/ renders the React SPA for role management, registered under the Security menu as "List Roles" . The legacy FAB RoleModelView is explicitly removed during security manager initialization via register_views() . The SUPERSET_SECURITY_VIEW_MENU config key (default: True) controls whether the Security menu is shown at all.
The role edit modal uses AsyncSelect with server-side search for the Permissions and Groups dropdowns (merged in PR #38387). This allows workspaces with >100 permissions to search without loading all options upfront — matching the existing pattern used by UsersField. Permissions are searched by dual-column match: view_menu.name and permission.name in parallel. On modal open, existing permission IDs are hydrated to labels via an in filter; any unresolvable IDs appear as numeric fallback pills with a warning toast.
Migration-Time Permission Management#
superset/migrations/shared/security_converge.py provides utilities for Alembic migrations to rename or restructure PVMs without losing role assignments :
add_pvms()— creates new Permission, ViewMenu, and PVM records if absentmigrate_roles()— maps old PVMs to new ones across all roles, then deletes old records_delete_old_permissions()— removes orphaned PVMs, permission names, and view menus post-migration
Key Methods in SupersetSecurityManager#
All methods are in superset/security/manager.py:
| Method | Lines | Purpose |
|---|---|---|
sync_role_definitions() | 1098–1123 | Orchestrates full role/permission sync; creates custom perms, rebuilds built-in roles, cleans orphans |
set_role() | 1198–1216 | Rebuilds a role's PVM list using a predicate function |
copy_role() | 1167–1196 | Copies PVMs from one role to another; merge=True preserves existing data-access permissions on the target |
get_user_roles() | 2472–2478 | Returns a user's roles; returns the public role for anonymous users if AUTH_ROLE_PUBLIC is set |
create_custom_permissions() | 1032–1047 | Registers Superset-specific PVMs (e.g. all_datasource_access, can_sqllab, can_tag) |
clean_perms() | 1081–1096 | Deletes PVMs where either Permission or ViewMenu side is NULL |
create_missing_perms() | 1049–1079 | Adds PVMs for database/dataset/schema objects not yet covered |
copy_role() is used by sync_role_definitions() to optionally mirror a role's permissions onto the Public role via the PUBLIC_ROLE_LIKE config key .
Known Issue: PermissionViewMenuApi Filter Errors (v6.0–v6.1)#
In Superset v6.0 and v6.1, the role edit form's permission dropdown can fail with HTTP 400 "Filter column: id not allowed to filter" . This also affects search queries filtering by view_menu.name or permission.name.
Root cause: FAB's built-in PermissionViewMenuApi does not declare search_columns for id or dot-notation relationship columns, so those filters are rejected . The frontend fix (PR #38387, merged March 2026) actively uses these filters via AsyncSelect, which triggers the backend rejection on older FAB versions.
Resolution: PR #37815 fixed this on master by adding filter support to PermissionViewMenuApi, but landed after the v6.1.0 release cut . It will be included in the next release after 6.1.0.
Workaround for v6.1 deployments: Override PermissionViewMenuApi to inject the missing search_filters entries via FLASK_APP_MUTATOR or a custom superset_config.py mounted at /app/pythonpath/superset_config.py . Users on v6.1 also report this is resolvable by patching the FAB source directly .
Key Source Files#
| File | Purpose |
|---|---|
superset/security/manager.py | SupersetSecurityManager — all role/PVM CRUD, role sync, copy_role, get_user_roles |
superset/security/api.py | RoleRestAPI (role listing/search), SecurityRestApi (CSRF/guest tokens) |
superset/cli/main.py | superset init — triggers role/permission sync |
superset/migrations/shared/security_converge.py | Migration utilities: migrate_roles(), add_pvms(), _delete_old_permissions() |
superset/cli/importexport.py | Import/export CLI — no dedicated role export commands |