0
# Security and Authentication
1
2
Enterprise-grade security system with role-based access control, row-level security, OAuth integration, and comprehensive permission management.
3
4
## Capabilities
5
6
### Security Manager
7
8
Core security management system built on Flask-AppBuilder.
9
10
```python { .api }
11
class SupersetSecurityManager(SecurityManager):
12
"""Enhanced security manager for Superset with custom permissions."""
13
14
def __init__(self, appbuilder: AppBuilder):
15
"""
16
Initialize security manager.
17
18
Args:
19
appbuilder: Flask-AppBuilder instance
20
"""
21
22
def get_user_menu_access(self, menu_names: List[str]) -> Set[str]:
23
"""
24
Get menus accessible to current user.
25
26
Args:
27
menu_names: List of menu names to check
28
29
Returns:
30
Set of accessible menu names
31
"""
32
33
def can_access(self, permission_name: str, view_name: str) -> bool:
34
"""
35
Check if current user has permission.
36
37
Args:
38
permission_name: Permission to check (can_read, can_write, etc.)
39
view_name: View/resource name
40
41
Returns:
42
True if user has permission
43
"""
44
45
def get_rls_filters(self, table: BaseDatasource) -> List[SqlaQuery]:
46
"""
47
Get row-level security filters for user and table.
48
49
Args:
50
table: Target datasource
51
52
Returns:
53
List of SQL filter conditions
54
"""
55
56
def get_datasource_access_error_msg(self, datasource: BaseDatasource) -> str:
57
"""
58
Get error message for datasource access denial.
59
60
Args:
61
datasource: Inaccessible datasource
62
63
Returns:
64
Human-readable error message
65
"""
66
67
def raise_for_access(self, permission_name: str = None,
68
view_name: str = None, **kwargs) -> None:
69
"""
70
Raise exception if user lacks permission.
71
72
Args:
73
permission_name: Required permission
74
view_name: Target view/resource
75
76
Raises:
77
SupersetSecurityException: If access denied
78
"""
79
80
def get_user_roles(self) -> List[Role]:
81
"""Get roles for current user."""
82
83
def is_admin(self) -> bool:
84
"""Check if current user is admin."""
85
86
def is_alpha(self) -> bool:
87
"""Check if current user has alpha role."""
88
89
def is_gamma(self) -> bool:
90
"""Check if current user has gamma role."""
91
```
92
93
**Usage Examples:**
94
95
```python
96
from superset import security_manager
97
98
# Check permissions
99
if security_manager.can_access('can_read', 'Dashboard'):
100
# User can read dashboards
101
pass
102
103
# Get accessible menus
104
accessible_menus = security_manager.get_user_menu_access(['SQL Lab', 'Charts'])
105
106
# Raise for access (will throw exception if denied)
107
security_manager.raise_for_access('can_edit', 'Chart')
108
```
109
110
### Authentication Types
111
112
Different authentication mechanisms supported by Superset.
113
114
```python { .api }
115
# Authentication Type Constants
116
AUTH_OID: int = 0 # OpenID authentication
117
AUTH_DB: int = 1 # Database authentication
118
AUTH_LDAP: int = 2 # LDAP authentication
119
AUTH_REMOTE_USER: int = 3 # Remote user authentication
120
AUTH_OAUTH: int = 4 # OAuth authentication
121
122
class AuthDBView(AuthView):
123
"""Database authentication view."""
124
125
def login(self) -> Response:
126
"""
127
Handle database login.
128
129
Returns:
130
Login response or redirect
131
"""
132
133
class AuthOAuthView(AuthView):
134
"""OAuth authentication view."""
135
136
def oauth_authorize(self, provider: str) -> Response:
137
"""
138
Initiate OAuth authorization flow.
139
140
Args:
141
provider: OAuth provider name
142
143
Returns:
144
Redirect to OAuth provider
145
"""
146
147
def oauth_authorized(self, provider: str) -> Response:
148
"""
149
Handle OAuth callback.
150
151
Args:
152
provider: OAuth provider name
153
154
Returns:
155
Login completion response
156
"""
157
158
class AuthLDAPView(AuthView):
159
"""LDAP authentication view."""
160
161
def authenticate(self, username: str, password: str) -> bool:
162
"""
163
Authenticate against LDAP server.
164
165
Args:
166
username: LDAP username
167
password: User password
168
169
Returns:
170
True if authentication successful
171
"""
172
```
173
174
**Usage Examples:**
175
176
```python
177
# Database authentication configuration
178
AUTH_TYPE = AUTH_DB
179
AUTH_USER_REGISTRATION = True
180
AUTH_USER_REGISTRATION_ROLE = "Gamma"
181
182
# OAuth configuration
183
AUTH_TYPE = AUTH_OAUTH
184
OAUTH_PROVIDERS = [{
185
'name': 'google',
186
'token_key': 'access_token',
187
'icon': 'fa-google',
188
'remote_app': {
189
'client_id': 'your-client-id',
190
'client_secret': 'your-client-secret',
191
'server_metadata_url': 'https://accounts.google.com/.well-known/openid_configuration',
192
'client_kwargs': {'scope': 'openid email profile'}
193
}
194
}]
195
```
196
197
### Permission System
198
199
Granular permission system for controlling access to resources.
200
201
```python { .api }
202
# Core Permission Classes
203
class Permission:
204
"""Permission for accessing resources."""
205
206
name: str # Permission name (can_read, can_write, etc.)
207
view_menu: ViewMenu # Target resource/view
208
209
def __init__(self, name: str, view_menu: ViewMenu):
210
"""
211
Initialize permission.
212
213
Args:
214
name: Permission type
215
view_menu: Target resource
216
"""
217
218
class ViewMenu:
219
"""Resource/view that can be protected."""
220
221
name: str # Resource name (Dashboard, Chart, etc.)
222
223
def __init__(self, name: str):
224
"""
225
Initialize view menu.
226
227
Args:
228
name: Resource name
229
"""
230
231
class Role:
232
"""Group of permissions assigned to users."""
233
234
name: str # Role name
235
permissions: List[Permission] # Assigned permissions
236
237
def __init__(self, name: str):
238
"""
239
Initialize role.
240
241
Args:
242
name: Role name
243
"""
244
245
# Permission Constants
246
PERMISSION_CAN_READ = "can_read"
247
PERMISSION_CAN_WRITE = "can_write"
248
PERMISSION_CAN_DELETE = "can_delete"
249
PERMISSION_CAN_LIST = "can_list"
250
PERMISSION_CAN_SHOW = "can_show"
251
PERMISSION_CAN_ADD = "can_add"
252
PERMISSION_CAN_EDIT = "can_edit"
253
254
# Resource Constants
255
RESOURCE_DASHBOARD = "Dashboard"
256
RESOURCE_CHART = "Chart"
257
RESOURCE_DATASET = "Dataset"
258
RESOURCE_DATABASE = "Database"
259
RESOURCE_SQL_LAB = "SQL Lab"
260
```
261
262
### Built-in Roles
263
264
Predefined roles with different permission levels.
265
266
```python { .api }
267
class DefaultRoles:
268
"""Default roles in Superset."""
269
270
ADMIN = "Admin" # Full system access
271
ALPHA = "Alpha" # Power user access
272
GAMMA = "Gamma" # Standard user access
273
PUBLIC = "Public" # Public/guest access
274
SQL = "sql_lab" # SQL Lab access
275
GRANTER = "granter" # Can grant permissions
276
277
def create_admin_role() -> Role:
278
"""
279
Create admin role with all permissions.
280
281
Returns:
282
Admin role with full access
283
"""
284
285
def create_alpha_role() -> Role:
286
"""
287
Create alpha role with power user permissions.
288
289
Returns:
290
Alpha role for power users
291
"""
292
293
def create_gamma_role() -> Role:
294
"""
295
Create gamma role with standard user permissions.
296
297
Returns:
298
Gamma role for standard users
299
"""
300
301
def create_public_role() -> Role:
302
"""
303
Create public role for guest access.
304
305
Returns:
306
Public role with limited access
307
"""
308
```
309
310
**Usage Examples:**
311
312
```python
313
# Check user roles
314
from superset import security_manager
315
316
user = security_manager.get_user()
317
if security_manager.is_admin():
318
# User has admin privileges
319
pass
320
321
# Get user permissions
322
user_permissions = []
323
for role in user.roles:
324
user_permissions.extend(role.permissions)
325
```
326
327
### Row-Level Security
328
329
Fine-grained data access control at the row level.
330
331
```python { .api }
332
class RowLevelSecurityFilter(Model):
333
"""Row-level security filter definition."""
334
335
id: int
336
filter_type: str # SQL or Regular
337
tables: List[SqlaTable] # Target tables
338
roles: List[Role] # Applicable roles
339
group_key: str # Grouping key for filters
340
clause: str # SQL WHERE clause
341
342
def __init__(self, filter_type: str = "Regular", clause: str = None,
343
**kwargs):
344
"""
345
Initialize RLS filter.
346
347
Args:
348
filter_type: Type of filter (SQL or Regular)
349
clause: SQL WHERE clause for filtering
350
"""
351
352
def get_rls_filters(datasource: BaseDatasource,
353
user: User = None) -> List[str]:
354
"""
355
Get applicable RLS filters for datasource and user.
356
357
Args:
358
datasource: Target datasource
359
user: User to get filters for (current user if None)
360
361
Returns:
362
List of SQL WHERE clauses to apply
363
"""
364
365
def apply_rls_filters(query: str, filters: List[str]) -> str:
366
"""
367
Apply RLS filters to SQL query.
368
369
Args:
370
query: Original SQL query
371
filters: List of filter clauses
372
373
Returns:
374
Modified query with filters applied
375
"""
376
```
377
378
**Usage Examples:**
379
380
```python
381
# Create RLS filter
382
rls_filter = RowLevelSecurityFilter(
383
filter_type="Regular",
384
clause="department = '{{ current_user_id() }}'"
385
)
386
rls_filter.tables.append(sales_table)
387
rls_filter.roles.append(gamma_role)
388
389
# Apply RLS in query execution
390
filters = get_rls_filters(datasource, current_user)
391
filtered_query = apply_rls_filters(original_query, filters)
392
```
393
394
### User Management
395
396
User creation, role assignment, and profile management.
397
398
```python { .api }
399
class UserManager:
400
"""User management utilities."""
401
402
def create_user(self, username: str, email: str, first_name: str,
403
last_name: str, password: str, role: Role) -> User:
404
"""
405
Create new user.
406
407
Args:
408
username: Login username
409
email: Email address
410
first_name: First name
411
last_name: Last name
412
password: Initial password
413
role: Primary role
414
415
Returns:
416
Created user instance
417
"""
418
419
def update_user_roles(self, user: User, roles: List[Role]) -> None:
420
"""
421
Update user's role assignments.
422
423
Args:
424
user: Target user
425
roles: New role list
426
"""
427
428
def deactivate_user(self, user: User) -> None:
429
"""
430
Deactivate user account.
431
432
Args:
433
user: User to deactivate
434
"""
435
436
def reset_password(self, user: User, new_password: str) -> None:
437
"""
438
Reset user password.
439
440
Args:
441
user: Target user
442
new_password: New password
443
"""
444
445
def get_current_user() -> User:
446
"""Get currently authenticated user."""
447
448
def get_user_by_username(username: str) -> User:
449
"""Get user by username."""
450
451
def get_user_roles(user: User) -> List[Role]:
452
"""Get roles assigned to user."""
453
```
454
455
### API Security
456
457
JWT-based API authentication and authorization.
458
459
```python { .api }
460
class JWTManager:
461
"""JWT token management for API access."""
462
463
def generate_token(self, user: User, expires_delta: timedelta = None) -> str:
464
"""
465
Generate JWT access token.
466
467
Args:
468
user: User to generate token for
469
expires_delta: Token expiration time
470
471
Returns:
472
JWT access token
473
"""
474
475
def verify_token(self, token: str) -> User:
476
"""
477
Verify and decode JWT token.
478
479
Args:
480
token: JWT token to verify
481
482
Returns:
483
User associated with token
484
485
Raises:
486
TokenError: If token invalid or expired
487
"""
488
489
def refresh_token(self, refresh_token: str) -> str:
490
"""
491
Generate new access token from refresh token.
492
493
Args:
494
refresh_token: Valid refresh token
495
496
Returns:
497
New access token
498
"""
499
500
def create_guest_token(resources: List[Dict[str, Any]],
501
user_data: Dict[str, Any] = None) -> str:
502
"""
503
Create guest access token for embedded dashboards.
504
505
Args:
506
resources: List of accessible resources
507
user_data: Guest user attributes
508
509
Returns:
510
Guest access token
511
"""
512
```
513
514
**Usage Examples:**
515
516
```python
517
# Generate API token
518
from superset.utils import jwt
519
520
user = get_current_user()
521
token = jwt.generate_token(user)
522
523
# Use token in API calls
524
headers = {'Authorization': f'Bearer {token}'}
525
response = requests.get('/api/v1/dashboard/', headers=headers)
526
527
# Create guest token for embedded dashboard
528
guest_token = create_guest_token([
529
{'type': 'dashboard', 'id': 123}
530
], {'username': 'guest', 'first_name': 'Guest'})
531
```
532
533
## Security Configuration
534
535
### Security Settings
536
537
```python { .api }
538
# Core security settings
539
SECRET_KEY: str = "your-secret-key"
540
WTF_CSRF_ENABLED: bool = True
541
WTF_CSRF_TIME_LIMIT: int = 3600
542
543
# Session security
544
SESSION_COOKIE_SECURE: bool = True
545
SESSION_COOKIE_HTTPONLY: bool = True
546
SESSION_COOKIE_SAMESITE: str = "Lax"
547
PERMANENT_SESSION_LIFETIME: timedelta = timedelta(days=31)
548
549
# Password policies
550
AUTH_PASSWORD_COMPLEXITY_ENABLED: bool = True
551
AUTH_PASSWORD_MIN_LENGTH: int = 8
552
AUTH_PASSWORD_COMPLEXITY_VALIDATOR: Callable = None
553
554
# Login attempt limits
555
AUTH_RATE_LIMITED: bool = True
556
AUTH_RATE_LIMIT: str = "5 per 40 second"
557
```