0
# Role and Permission Management
1
2
Role-based access control with granular permission management. Supports creating roles, managing permissions, and implementing fine-grained access control for resources and actions in the Airflow security system.
3
4
## Capabilities
5
6
### Role Management
7
8
Create, update, and manage user roles with comprehensive role lifecycle operations.
9
10
```python { .api }
11
def add_role(self, name: str) -> Role | None:
12
"""
13
Create a new role.
14
15
Parameters:
16
- name: Unique name for the role
17
18
Returns:
19
Role object if created successfully, None if role already exists
20
"""
21
22
def update_role(self, role_id: int, name: str) -> Role | None:
23
"""
24
Update an existing role's name.
25
26
Parameters:
27
- role_id: ID of the role to update
28
- name: New name for the role
29
30
Returns:
31
Updated Role object if successful, None otherwise
32
"""
33
34
def find_role(self, name: str) -> Role | None:
35
"""
36
Find role by name.
37
38
Parameters:
39
- name: Role name to search for
40
41
Returns:
42
Role object if found, None otherwise
43
"""
44
45
def get_all_roles(self) -> list[Role]:
46
"""
47
Get all roles in the system.
48
49
Returns:
50
List of all Role objects
51
"""
52
53
def get_public_role(self) -> Role | None:
54
"""
55
Get the public/anonymous role.
56
57
Returns:
58
Public Role object if configured, None otherwise
59
"""
60
```
61
62
### Permission Management
63
64
Create and manage permissions linking actions to resources for fine-grained access control.
65
66
```python { .api }
67
def create_permission(self, action_name: str, resource_name: str) -> Permission | None:
68
"""
69
Create a permission linking an action to a resource.
70
71
Parameters:
72
- action_name: Name of the action (e.g., 'can_read', 'can_edit')
73
- resource_name: Name of the resource (e.g., 'Users', 'DAGs')
74
75
Returns:
76
Permission object if created successfully, None otherwise
77
"""
78
79
def get_permission(self, action_name: str, resource_name: str) -> Permission | None:
80
"""
81
Get existing permission by action and resource names.
82
83
Parameters:
84
- action_name: Name of the action
85
- resource_name: Name of the resource
86
87
Returns:
88
Permission object if found, None otherwise
89
"""
90
91
def delete_permission(self, action_name: str, resource_name: str) -> None:
92
"""
93
Delete a permission linking an action to a resource.
94
95
Parameters:
96
- action_name: Name of the action
97
- resource_name: Name of the resource
98
"""
99
```
100
101
### Role-Permission Assignment
102
103
Assign and remove permissions from roles to control access.
104
105
```python { .api }
106
def add_permission_to_role(self, role: Role, permission: Permission) -> None:
107
"""
108
Add a permission to a role.
109
110
Parameters:
111
- role: Role object to add permission to
112
- permission: Permission object to add
113
"""
114
115
def remove_permission_from_role(self, role: Role, permission: Permission) -> None:
116
"""
117
Remove a permission from a role.
118
119
Parameters:
120
- role: Role object to remove permission from
121
- permission: Permission object to remove
122
"""
123
```
124
125
### Action Management
126
127
Manage action definitions that define what operations can be performed.
128
129
```python { .api }
130
def create_action(self, name: str) -> Action | None:
131
"""
132
Create a new action.
133
134
Parameters:
135
- name: Action name (e.g., 'can_read', 'can_create', 'can_delete')
136
137
Returns:
138
Action object if created successfully, existing Action if already exists
139
"""
140
141
def get_action(self, name: str) -> Action | None:
142
"""
143
Get an existing action by name.
144
145
Parameters:
146
- name: Action name to retrieve
147
148
Returns:
149
Action object if found, None otherwise
150
"""
151
152
def delete_action(self, name: str) -> bool:
153
"""
154
Delete an action.
155
156
Parameters:
157
- name: Name of action to delete
158
159
Returns:
160
True if deletion successful, False otherwise
161
"""
162
```
163
164
### Resource Management
165
166
Manage resource definitions that represent objects or areas being protected.
167
168
```python { .api }
169
def create_resource(self, name: str) -> Resource:
170
"""
171
Create a new resource.
172
173
Parameters:
174
- name: Resource name (e.g., 'Users', 'DAGs', 'Connections')
175
176
Returns:
177
Resource object (existing if already exists, new if created)
178
"""
179
180
def get_resource(self, name: str) -> Resource | None:
181
"""
182
Get an existing resource by name.
183
184
Parameters:
185
- name: Resource name to retrieve
186
187
Returns:
188
Resource object if found, None otherwise
189
"""
190
191
def get_all_resources(self) -> list[Resource]:
192
"""
193
Get all resources in the system.
194
195
Returns:
196
List of all Resource objects
197
"""
198
199
def delete_resource(self, name: str) -> bool:
200
"""
201
Delete a resource.
202
203
Parameters:
204
- name: Name of resource to delete
205
206
Returns:
207
True if deletion successful, False otherwise
208
"""
209
210
def get_resource_permissions(self, resource: Resource) -> list[Permission]:
211
"""
212
Get all permissions associated with a resource.
213
214
Parameters:
215
- resource: Resource object to get permissions for
216
217
Returns:
218
List of Permission objects associated with the resource
219
"""
220
```
221
222
### Permission Queries
223
224
Query and validate permissions for authorization checks.
225
226
```python { .api }
227
def permission_exists_in_one_or_more_roles(
228
self,
229
resource_name: str,
230
action_name: str,
231
role_ids: list[int]
232
) -> bool:
233
"""
234
Check if a permission exists in any of the specified roles.
235
236
Parameters:
237
- resource_name: Name of the resource
238
- action_name: Name of the action
239
- role_ids: List of role IDs to check
240
241
Returns:
242
True if permission exists in at least one role, False otherwise
243
"""
244
245
def filter_roles_by_perm_with_action(
246
self,
247
action_name: str,
248
role_ids: list[int]
249
) -> list[Permission]:
250
"""
251
Find permissions with specific action in the given roles.
252
253
Parameters:
254
- action_name: Name of the action to filter by
255
- role_ids: List of role IDs to search in
256
257
Returns:
258
List of Permission objects matching the criteria
259
"""
260
261
def perms_include_action(self, perms: list[Permission], action_name: str) -> bool:
262
"""
263
Check if a list of permissions includes a specific action.
264
265
Parameters:
266
- perms: List of Permission objects
267
- action_name: Action name to check for
268
269
Returns:
270
True if action is found in permissions, False otherwise
271
"""
272
```
273
274
### Role Key Mapping
275
276
Map external role keys to internal roles for integration with external systems.
277
278
```python { .api }
279
def get_roles_from_keys(self, role_keys: list[str]) -> set[Role]:
280
"""
281
Get roles from external role keys using AUTH_ROLES_MAPPING.
282
283
Parameters:
284
- role_keys: List of external role identifiers (LDAP groups, OAuth roles, etc.)
285
286
Returns:
287
Set of Role objects mapped from the keys
288
"""
289
```
290
291
## Usage Examples
292
293
### Basic Role and Permission Setup
294
295
```python
296
from airflow.www.fab_security.sqla.manager import SecurityManager
297
298
# Create roles
299
admin_role = security_manager.add_role("DataAdmin")
300
viewer_role = security_manager.add_role("DataViewer")
301
302
# Create actions and resources
303
read_action = security_manager.create_action("can_read")
304
edit_action = security_manager.create_action("can_edit")
305
dag_resource = security_manager.create_resource("DAGs")
306
307
# Create permissions
308
read_dags_perm = security_manager.create_permission("can_read", "DAGs")
309
edit_dags_perm = security_manager.create_permission("can_edit", "DAGs")
310
311
# Assign permissions to roles
312
security_manager.add_permission_to_role(admin_role, read_dags_perm)
313
security_manager.add_permission_to_role(admin_role, edit_dags_perm)
314
security_manager.add_permission_to_role(viewer_role, read_dags_perm)
315
```
316
317
### Permission Validation
318
319
```python
320
# Check if user has specific permissions
321
user = security_manager.find_user(username="john_doe")
322
role_ids = [role.id for role in user.roles]
323
324
has_read_permission = security_manager.permission_exists_in_one_or_more_roles(
325
"DAGs", "can_read", role_ids
326
)
327
328
if has_read_permission:
329
print("User can read DAGs")
330
```
331
332
### Role Management
333
334
```python
335
# Find and update role
336
role = security_manager.find_role("DataAdmin")
337
if role:
338
# Add new permission
339
delete_perm = security_manager.create_permission("can_delete", "DAGs")
340
security_manager.add_permission_to_role(role, delete_perm)
341
342
# Remove permission
343
edit_perm = security_manager.get_permission("can_edit", "DAGs")
344
security_manager.remove_permission_from_role(role, edit_perm)
345
```
346
347
### External Role Mapping
348
349
```python
350
# Map LDAP groups to internal roles
351
ldap_groups = ["cn=airflow-admins,ou=groups,dc=company,dc=com"]
352
mapped_roles = security_manager.get_roles_from_keys(ldap_groups)
353
354
for role in mapped_roles:
355
print(f"Mapped to role: {role.name}")
356
```
357
358
### Resource and Action Cleanup
359
360
```python
361
# Get all resources and their permissions
362
all_resources = security_manager.get_all_resources()
363
for resource in all_resources:
364
permissions = security_manager.get_resource_permissions(resource)
365
print(f"Resource {resource.name} has {len(permissions)} permissions")
366
367
# Clean up unused actions
368
unused_action = security_manager.get_action("obsolete_action")
369
if unused_action:
370
success = security_manager.delete_action("obsolete_action")
371
if success:
372
print("Cleaned up obsolete action")
373
```
374
375
## Built-in Roles
376
377
The system supports built-in roles configured via `FAB_ROLES`:
378
- Roles defined in configuration are automatically created
379
- Built-in roles can have regex-based permission patterns
380
- Custom roles can be added alongside built-in roles
381
382
## Error Handling
383
384
Role and permission operations include comprehensive error handling:
385
- Duplicate role creation returns existing role
386
- Missing permissions or roles return `None`
387
- Database constraint violations are caught and logged
388
- Permission deletion checks for usage in roles
389
- Resource deletion validates no permissions exist