访问控制¶
Airflow Webserver UI 的访问控制由 Flask AppBuilder (FAB) 处理。请阅读其相关的安全文档,了解其安全模型。
默认角色¶
Airflow 默认提供一组角色:Admin、User、Op、Viewer 和 Public。默认情况下,只有 Admin
用户可以配置/更改角色的权限。但是,建议保持这些默认角色不变,而是让 Admin
用户在必要时创建具有所需权限的新角色。
公共¶
Public
用户(匿名)没有任何权限。
查看者¶
Viewer
用户具有有限的读取权限。
VIEWER_PERMISSIONS = [
(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_DEPENDENCIES),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_CODE),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_RUN),
(permissions.ACTION_CAN_READ, RESOURCE_ASSET),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_CLUSTER_ACTIVITY),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_POOL),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_IMPORT_ERROR),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_DAG_WARNING),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_JOB),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_MY_PASSWORD),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_MY_PASSWORD),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_MY_PROFILE),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_MY_PROFILE),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_SLA_MISS),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_TASK_INSTANCE),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_TASK_LOG),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_XCOM),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_BROWSE_MENU),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DAG),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DAG_DEPENDENCIES),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DAG_RUN),
(permissions.ACTION_CAN_ACCESS_MENU, RESOURCE_ASSET),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_CLUSTER_ACTIVITY),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DOCS),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_DOCS_MENU),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_JOB),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_SLA_MISS),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_TASK_INSTANCE),
]
用户¶
User
用户具有 Viewer
权限以及其他权限。
USER_PERMISSIONS = [
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_DAG),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_DAG),
(permissions.ACTION_CAN_CREATE, permissions.RESOURCE_TASK_INSTANCE),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_TASK_INSTANCE),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_TASK_INSTANCE),
(permissions.ACTION_CAN_CREATE, permissions.RESOURCE_DAG_RUN),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_DAG_RUN),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_DAG_RUN),
(permissions.ACTION_CAN_CREATE, RESOURCE_ASSET),
]
操作员¶
Op
用户具有 User
权限以及其他权限。
OP_PERMISSIONS = [
(permissions.ACTION_CAN_READ, permissions.RESOURCE_CONFIG),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_ADMIN_MENU),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_CONFIG),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_CONNECTION),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_POOL),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_PLUGIN),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_VARIABLE),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_PROVIDER),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_XCOM),
(permissions.ACTION_CAN_CREATE, permissions.RESOURCE_CONNECTION),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_CONNECTION),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_CONNECTION),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_CONNECTION),
(permissions.ACTION_CAN_CREATE, permissions.RESOURCE_POOL),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_POOL),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_POOL),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_PLUGIN),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_PROVIDER),
(permissions.ACTION_CAN_CREATE, permissions.RESOURCE_VARIABLE),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_VARIABLE),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_VARIABLE),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_VARIABLE),
(permissions.ACTION_CAN_DELETE, permissions.RESOURCE_XCOM),
(permissions.ACTION_CAN_DELETE, RESOURCE_ASSET),
(permissions.ACTION_CAN_CREATE, RESOURCE_ASSET),
]
管理员¶
Admin
用户具有所有可能的权限,包括授予或撤销其他用户的权限。 Admin
用户具有 Op
权限以及其他权限。
ADMIN_PERMISSIONS = [
(permissions.ACTION_CAN_READ, permissions.RESOURCE_AUDIT_LOG),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_AUDIT_LOG),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_TASK_RESCHEDULE),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_TASK_RESCHEDULE),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_TRIGGER),
(permissions.ACTION_CAN_ACCESS_MENU, permissions.RESOURCE_TRIGGER),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_PASSWORD),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_PASSWORD),
(permissions.ACTION_CAN_READ, permissions.RESOURCE_ROLE),
(permissions.ACTION_CAN_EDIT, permissions.RESOURCE_ROLE),
]
自定义角色¶
DAG 级别角色¶
Admin
可以创建一组角色,这些角色只允许查看某些 DAG。这称为 DAG 级别访问。DAG 模型表中定义的每个 DAG 都被视为一个 View
,它具有两个相关联的权限(can_read
和 can_edit
。can_dag_read
和 can_dag_edit
自 2.0.0 起已弃用)。有一个特殊的视图称为 DAGs
(在 1.10.* 版本中称为 all_dags
),它允许角色访问所有 DAG。默认的 Admin
、Viewer
、User
、Op
角色都可以访问 DAGs
视图。
该图像显示了创建一个只能写入 example_python_operator
的角色的过程。您也可以使用 airflow roles create
命令通过 CLI 创建角色,例如:
airflow roles create Role1 Role2
我们可以使用 airflow users add-role
CLI 命令将给定角色分配给新用户。
权限¶
警告
Airflow 允许您为用户定义具有细粒度 RBAC 权限的自定义角色。但是,并非所有权限组合都完全一致,并且没有机制来确保分配的权限集完全一致。在某些情况下,特定资源的权限是重叠的。菜单访问权限就是一个很好的例子——缺少菜单访问权限并不会自动禁用对菜单指向的功能的访问。另一个例子是访问角色视图,即使用户没有“用户视图”访问权限,也可以访问用户信息。当您无法访问用户时,添加对角色的访问权限是不一致的。
当您决定使用自定义的基于资源的权限集时,部署管理器应仔细检查授予角色的最终权限集是否符合他们的预期。
基于资源的权限¶
从 2.0 版本开始,权限基于各个资源和这些资源上的一小部分操作。资源与标准的 Airflow 概念匹配,例如 Dag
、DagRun
、Task
和 Connection
。操作包括 can_create
、can_read
、can_edit
和 can_delete
。
然后将权限(每个权限由资源+操作对组成)添加到角色。
要访问端点,用户需要分配给该端点的所有权限。
有五个默认角色:Public、Viewer、User、Op 和 Admin。每个角色都具有前面角色的权限,以及其他权限。
DAG 级别权限¶
对于 DAG 级别权限,可以控制所有 DAG 或单个 DAG 对象的访问权限。这包括 DAGs.can_read
、DAGs.can_edit
、DAGs.can_delete
、DAG Runs.can_read
、DAG Runs.can_create
、DAG Runs.can_delete
和 DAG Runs.menu_access
。当列出这些权限时,如果用户具有列出的权限或对正在操作的特定 DAG 具有相同的权限,则会授予访问权限。对于单个 DAG,资源名称为 DAG:
+ DAG ID,对于 DAG Runs 资源,资源名称为 DAG Run:
。
例如,如果用户正在尝试查看 example_dag_id
的 DAG 信息,并且该端点需要 DAGs.can_read
访问权限,则如果用户具有 DAGs.can_read
或 DAG:example_dag_id.can_read
访问权限,则会授予访问权限。
稳定 API 权限 |
|||
---|---|---|---|
端点 |
方法 |
权限 |
最低角色 |
/config |
GET |
Configurations.can_read |
Op |
/connections |
GET |
Connections.can_read |
Op |
/connections |
POST |
Connections.can_create |
Op |
/connections/{connection_id} |
DELETE |
Connections.can_delete |
Op |
/connections/{connection_id} |
PATCH |
Connections.can_edit |
Op |
/connections/{connection_id} |
GET |
Connections.can_read |
Op |
/dagSources/{file_token} |
GET |
DAG Code.can_read |
Viewer |
/dags |
GET |
DAGs.can_read |
Viewer |
/dags/{dag_id} |
GET |
DAGs.can_read |
Viewer |
/dags/{dag_id} |
PATCH |
DAGs.can_edit |
User |
/dags/{dag_id}/clearTaskInstances |
PUT |
DAGs.can_edit, DAG Runs.can_edit, Task Instances.can_edit |
User |
/dags/{dag_id}/details |
GET |
DAGs.can_read |
Viewer |
/dags/{dag_id}/tasks |
GET |
DAGs.can_read, Task Instances.can_read |
Viewer |
/dags/{dag_id}/tasks/{task_id} |
GET |
DAGs.can_read, Task Instances.can_read |
Viewer |
/dags/{dag_id}/dagRuns |
GET |
DAGs.can_read, DAG Runs.can_read |
Viewer |
/dags/{dag_id}/dagRuns |
POST |
DAGs.can_edit, DAG Runs.can_create |
User |
/dags/{dag_id}/dagRuns/{dag_run_id} |
DELETE |
DAGs.can_edit, DAG Runs.can_delete |
User |
/dags/{dag_id}/dagRuns/{dag_run_id} |
GET |
DAGs.can_read, DAG Runs.can_read |
Viewer |
/dags/~/dagRuns/list |
POST |
DAGs.can_edit, DAG Runs.can_read |
User |
/assets |
GET |
Assets.can_read |
Viewer |
/assets/{uri} |
GET |
Assets.can_read |
Viewer |
/assets/events |
GET |
Assets.can_read |
Viewer |
/eventLogs |
GET |
Audit Logs.can_read |
Viewer |
/eventLogs/{event_log_id} |
GET |
Audit Logs.can_read |
Viewer |
/importErrors |
GET |
ImportError.can_read |
Viewer |
/importErrors/{import_error_id} |
GET |
ImportError.can_read |
Viewer |
/health |
GET |
无 |
公共 |
/version |
GET |
无 |
公共 |
/pools |
GET |
Pools.can_read |
Op |
/pools |
POST |
Pools.can_create |
Op |
/pools/{pool_name} |
DELETE |
Pools.can_delete |
Op |
/pools/{pool_name} |
GET |
Pools.can_read |
Op |
/pools/{pool_name} |
PATCH |
Pools.can_edit |
Op |
/providers |
GET |
Providers.can_read |
Op |
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances |
GET |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read |
Viewer |
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id} |
GET |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read |
Viewer |
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/links |
GET |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read |
Viewer |
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/logs/{task_try_number} |
GET |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read |
Viewer |
/dags/~/dagRuns/~/taskInstances/list |
POST |
DAGs.can_edit, DAG Runs.can_read, Task Instances.can_read |
User |
/variables |
GET |
Variables.can_read |
Op |
/variables |
POST |
变量.can_create |
Op |
/variables/{variable_key} |
DELETE |
变量.can_delete |
Op |
/variables/{variable_key} |
GET |
Variables.can_read |
Op |
/variables/{variable_key} |
PATCH |
变量.can_edit |
Op |
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries |
GET |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read, XComs.can_read |
Viewer |
/dags/{dag_id}/dagRuns/{dag_run_id}/taskInstances/{task_id}/xcomEntries/{xcom_key} |
GET |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read, XComs.can_read |
Viewer |
/users |
GET |
用户.can_read |
管理员 |
/users |
POST |
用户.can_create |
管理员 |
/users/{username} |
GET |
用户.can_read |
管理员 |
/users/{username} |
PATCH |
用户.can_edit |
管理员 |
/users/{username} |
DELETE |
用户.can_delete |
管理员 |
/roles |
GET |
角色.can_read |
管理员 |
/roles |
POST |
角色.can_create |
管理员 |
/roles/{role_name} |
GET |
角色.can_read |
管理员 |
/roles/{role_name} |
PATCH |
角色.can_edit |
管理员 |
/roles/{role_name} |
DELETE |
角色.can_delete |
管理员 |
/permissions |
GET |
权限视图.can_read |
管理员 |
网站权限 |
||
---|---|---|
操作 |
权限 |
最低角色 |
访问首页 |
网站.can_read |
Viewer |
显示浏览菜单 |
浏览.menu_access |
Viewer |
显示 DAGs 菜单 |
DAGs.menu_access |
Viewer |
获取 DAG 统计信息 |
DAGs.can_read, DAG Runs.can_read |
Viewer |
显示任务实例菜单 |
任务实例.menu_access |
Viewer |
获取任务统计信息 |
DAGs.can_read, DAG Runs.can_read, Task Instances.can_read |
Viewer |
获取最后 DAG 运行记录 |
DAGs.can_read, DAG Runs.can_read |
Viewer |
获取 DAG 代码 |
DAGs.can_read, DAG 代码.can_read |
Viewer |
获取 DAG 详情 |
DAGs.can_read, DAG Runs.can_read |
Viewer |
显示 DAG 依赖关系菜单 |
DAG 依赖关系.menu_access |
Viewer |
获取 DAG 依赖关系 |
DAG 依赖关系.can_read |
Viewer |
获取渲染的 DAG |
DAGs.can_read, Task Instances.can_read |
Viewer |
获取带有元数据的日志 |
DAGs.can_read, 任务实例.can_read, 任务日志.can_read |
Viewer |
获取日志 |
DAGs.can_read, 任务实例.can_read, 任务日志.can_read |
Viewer |
重定向到外部日志 |
DAGs.can_read, 任务实例.can_read, 任务日志.can_read |
Viewer |
获取任务 |
DAGs.can_read, Task Instances.can_read |
Viewer |
显示 XCom 菜单 |
XComs.menu_access |
Op |
获取 XCom |
DAGs.can_read, 任务实例.can_read, XComs.can_read |
Viewer |
创建 XCom |
XComs.can_create |
Op |
删除 XCom |
XComs.can_delete |
Op |
触发任务实例 |
DAGs.can_edit, 任务实例.can_create |
User |
删除 DAG |
DAGs.can_delete |
User |
显示 DAG 运行菜单 |
DAG 运行.menu_access |
Viewer |
触发 DAG 运行 |
DAGs.can_edit, DAG Runs.can_create |
User |
清除 DAG |
DAGs.can_edit, 任务实例.can_delete |
User |
清除 DAG 运行 |
DAGs.can_edit, 任务实例.can_delete |
User |
将 DAG 标记为阻塞 |
DAGS.can_edit, DAG 运行.can_read |
User |
将 DAG 运行标记为失败 |
DAGS.can_edit, DAG 运行.can_edit |
User |
将 DAG 运行标记为成功 |
DAGS.can_edit, DAG 运行.can_edit |
User |
将任务标记为失败 |
DAGs.can_edit, 任务实例.can_edit |
User |
将任务标记为成功 |
DAGs.can_edit, 任务实例.can_edit |
User |
将 DAG 作为树获取 |
DAGs.can_read, 任务实例.can_read, 任务日志.can_read |
Viewer |
将 DAG 作为图获取 |
DAGs.can_read, 任务实例.can_read, 任务日志.can_read |
Viewer |
将 DAG 作为时长图获取 |
DAGs.can_read, Task Instances.can_read |
Viewer |
显示所有尝试 |
DAGs.can_read, Task Instances.can_read |
Viewer |
显示落地时间 |
DAGs.can_read, Task Instances.can_read |
Viewer |
切换 DAG 暂停状态 |
DAGs.can_edit |
User |
显示甘特图 |
DAGs.can_read, Task Instances.can_read |
Viewer |
获取外部链接 |
DAGs.can_read, Task Instances.can_read |
Viewer |
显示任务实例 |
DAGs.can_read, Task Instances.can_read |
Viewer |
显示配置菜单 |
配置.menu_access |
Op |
显示配置 |
Configurations.can_read |
Viewer |
删除多个记录 |
DAGs.can_edit |
User |
将任务实例设置为正在运行 |
DAGs.can_edit |
User |
将任务实例设置为失败 |
DAGs.can_edit |
User |
将任务实例设置为成功 |
DAGs.can_edit |
User |
将任务实例设置为可重试 |
DAGs.can_edit |
User |
自动完成 |
DAGs.can_read |
Viewer |
显示资产菜单 |
资产.menu_access |
Viewer |
显示资产 |
Assets.can_read |
Viewer |
显示文档菜单 |
文档.menu_access |
Viewer |
显示文档菜单 |
文档.menu_access |
Viewer |
显示作业菜单 |
作业.menu_access |
Viewer |
显示审计日志 |
审计日志.menu_access |
Viewer |
重置密码 |
我的密码.can_read, 我的密码.can_edit |
Viewer |
显示权限菜单 |
权限视图.menu_access |
管理员 |
列出权限 |
权限视图.can_read |
管理员 |
获取我的个人资料 |
我的个人资料.can_read |
Viewer |
更新我的个人资料 |
我的个人资料.can_edit |
Viewer |
列出日志 |
Audit Logs.can_read |
Viewer |
列出作业 |
作业.can_read |
Viewer |
显示 SLA 错过菜单 |
SLA 错过.menu_access |
Viewer |
列出 SLA 错过 |
SLA 错过.can_read |
Viewer |
列出插件 |
插件.can_read |
Viewer |
显示插件菜单 |
插件.menu_access |
Viewer |
显示提供程序菜单 |
提供程序.menu_access |
Op |
列出提供程序 |
Providers.can_read |
Op |
列出任务重新调度 |
任务重新调度.can_read |
管理员 |
显示触发器菜单 |
触发器.menu_access |
管理员 |
列出触发器 |
触发器.can_read |
管理员 |
显示管理员菜单 |
管理员.menu_access |
Viewer |
显示连接菜单 |
连接.menu_access |
Op |
显示池菜单 |
池.menu_access |
Viewer |
显示变量菜单 |
变量.menu_access |
Op |
显示角色菜单 |
角色.menu_access |
管理员 |
列出角色 |
角色.can_read |
管理员 |
创建角色 |
角色.can_create |
管理员 |
更新角色 |
角色.can_edit |
管理员 |
删除角色 |
角色.can_delete |
管理员 |
显示用户菜单 |
用户.menu_access |
管理员 |
创建用户 |
用户.can_create |
管理员 |
更新用户 |
用户.can_edit |
管理员 |
删除用户 |
用户.can_delete |
管理员 |
重置用户密码 |
密码.can_edit, 密码.can_read |
管理员 |
这些 DAG 级别的控制可以通过 UI / CLI 直接设置,也可以通过 access_control 参数编码在 DAG 本身中。
DAG 级别权限的优先级顺序¶
由于 DAG 级别的访问控制可以在多个位置配置,冲突是不可避免的,因此需要一个明确的解决策略。因此,Airflow 认为 DAG 本身提供的 access_control
参数(如果存在)完全具有权威性,这会产生一些影响
如果 DAG 上的 access_control
设置为除 None
以外的任何值,将覆盖任何先前存在的 DAG 级别权限
DAG(
dag_id="example_fine_grained_access",
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
access_control={
"Viewer": {"can_edit", "can_read", "can_delete"},
},
)
也可以以类似的方式添加 DAG 运行资源权限,但显式添加资源名称以标识权限所属的资源
DAG(
dag_id="example_fine_grained_access",
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
access_control={
"Viewer": {"DAGs": {"can_edit", "can_read", "can_delete"}, "DAG Runs": {"can_create"}},
},
)
这也意味着设置 access_control={}
将从数据库中清除给定 DAG 的任何现有 DAG 级别权限
DAG(
dag_id="example_no_fine_grained_access",
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
access_control={},
)
相反,从 DAG 中完全删除 access_control 块(或将其设置为 None
)不会进行任何更改,并且可能会留下悬空的权限。
DAG(
dag_id="example_indifferent_to_fine_grained_access",
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
)
如果 DAG 本身没有定义 access_control
,Airflow 将会参考数据库中定义的现有权限,这些权限可能是通过 UI、CLI 或通过所讨论 DAG 上先前的 access_control 参数设置的。
在所有情况下,系统范围的角色(如 Can edit on DAG
)的优先级高于 DAG 级别的访问控制,因此可以将它们视为 Can edit on DAG: *