基本默认角色¶
管理 基于角色的访问控制 (RBAC) 在 OpenStack 中是操作员面临的最困难的痛点之一。操作员不得不深入源代码并记录 RBAC 实现中的一些奇怪之处,只是为了向他们的客户提供基本的 RBAC 功能,这并不罕见。最终用户也受到影响,因为很少有两套部署具有相似的角色,或者确保这些角色映射到相似的操作。
问题描述¶
OpenStack 最初的 RBAC 实现很简单,适用于简单的部署。随着 OpenStack 的发展以及部署开始模拟更大的、更复杂的组织,RBAC 实现未能与之同步发展。因此,操作员不得不使用现有的工具来提供更复杂的 RBAC 解决方案的表面文章。这对于自定义策略的操作员来说,是一个令人困惑且极其繁重的维护负担。
并非罕见,各种服务会将操作硬编码到特定角色。虽然该操作可能需要该角色,但角色到策略的映射应该由操作员可以覆盖的策略默认值驱动,而不是硬编码。
提议的变更¶
作为平台,OpenStack 应该提供一个基本的、易于理解的 RBAC 实现,具有清晰、合理的默认值。实施此过程将为操作员提供开箱即用的更多灵活性。它也更不可能由于现有实现的限制而导致跨部署的不一致性。
为了帮助确保平稳过渡,改进已应用于 oslo policy 库,并且社区 目标已到位,以帮助项目团队在代码中注册默认策略并提供文档。这项工作为 OpenStack 项目团队提供了改进默认角色定义的必要工具。更改后的默认值可以由操作员以与更改配置选项一致的方式使用。
本规范建议 Keystone 通过将其以下默认角色合并到其默认策略中来增强基本的 RBAC 体验。
此处详细介绍的工作可以分为两项举措。第一项是确保在安装后默认值可供操作员使用。第二项是将这些可用角色合并到跨服务的默认策略中。请注意,第一项举措在 Rocky 版本中已经完成。虽然本规范会详细描述第二项举措,但它将在后续版本(可能为 Stein 或更高版本)中实施。Keystone 中的第二项举措将需要着陆一个大型重构,以清理技术债务并将 Keystone 迁移到使用 flask 而不是自研的 WSGI 实现。在开始第二项举措之前,着陆此重构至关重要,因为它将使跨 Keystone 子系统中 Manager 层处理不同范围的 RBAC,就像处理正式的业务逻辑一样,而不是将更多复杂性混淆到当前大多数 API 使用的 @controller.protected 装饰器中。
我们的目标是这项工作将作为其他服务采用所提出的默认角色的模板,用于未来的 社区目标。
默认角色¶
reader:它仅应用于只读 API 和操作。或者称为 readonly 或 observer,此角色满足了操作员的极受欢迎的需求。
member:作为通用的“执行者”角色。它在管理员和所有其他用户之间引入了粒度。
admin:此角色仅被认为适用于被认为对具有成员角色的任何人来说过于敏感的操作。
实施上述角色的期望结果是,项目应该开始远离将操作硬编码到特定角色名称的做法。相反,每个策略都应该有一个合理的默认值,可以被操作员覆盖。
范围类型(复习)¶
project-scope:项目范围与在云的特定租户中运行授权有关。
system-scope:系统范围与运行不适合项目范围概念的 API 的授权有关。它不旨在涵盖部署中的所有 API。有关系统范围的更多信息,请参见 规范,以及证明 系统范围的必要性的相关历史背景。
示例¶
reader: 此角色的一个项目范围应用示例是列出项目标签 (identity:get_project_tags)。此角色的一个系统范围应用示例是列出服务端点 (identity:list_endpoints)。
member: 此角色的一个项目范围应用示例是创建项目标签 (identity:update_project_tags)。此角色的一个系统范围应用示例是更新端点 (identity:update_endpoint)。
admin: 一个项目范围的管理员操作示例是删除项目标签 (identity:delete_project_tags)。一个系统范围的管理员操作示例是为服务创建端点 (identity:create_endpoint) 或列出迁移 (os_compute_api:os-migrations)。
以下不是最终的或全面的所有可能规则/策略列表。它仅仅是现有规则的片段,用于展示策略、范围和新的默认角色如何协同工作,以提供更丰富的策略体验。
项目读取器¶
identity:list_project_tagsidentity:get_project_tag
项目成员¶
identity:list_project_tagsidentity:get_project_tagidentity:update_project_tags
项目管理员¶
identity:list_project_tagsidentity:get_project_tagidentity:update_project_tagsidentity:create_project_tagsidentity:delete_project_tags
系统读取器¶
identity:list_endpointsidentity:get_endpoint
系统成员¶
identity:list_endpointsidentity:get_endpointidentity:update_endpoints
系统管理员¶
identity:list_endpointsidentity:get_endpointidentity:update_endpointsidentity:create_endpointsos-compute-api:os-hypervisorsos-compute-api:os-migrations
以下是各种策略文件的示例片段,或呈现的片段,可以如下所示。
注意
将创建讨论的默认角色由 Keystone 在引导过程中使用 隐式角色。如上表所示,拥有 admin 角色意味着用户也具有与 member 角色相同的权利。因此,该用户也将具有与 reader 角色相同的权利,因为 member 意味着 reader。
这保持了策略文件的清洁。例如,以下是由于隐式角色而等效的
“identity:list_endpoints”: “role:reader OR role:member OR role:admin” “identity:list_endpoints”: “role:reader”
隐式角色的链将与 policy-in-code defaults 以及 Keystone 文档更新一起记录,并说明这一点。
# scope_types = ('project')
"identity:list_project_tags": "role:reader"
"identity:get_project_tag": "role:reader"
"identity:update_project_tags": "role:member"
"identity:create_project_tag": "role:admin"
"identity:delete_project_tags": "role:admin"
# scope_types = ('system')
"identity:list_endpoints": "role:reader"
"identity:get_endpoints": "role:reader"
"identity:update_endpoint": "role:member"
"identity:create_endpoint": "role:admin"
"os_compute_api:os-hypervisors": "role:admin"
"os_compute_api:os-migrations": "role:admin"
假设存在以下角色分配
Alice 在系统上具有 reader 角色
Bob 在系统上具有 member 角色
Charlie 在系统上具有 admin 角色
Qiana 在项目 Alpha 上具有 reader 角色
Rebecca 在项目 Alpha 上具有 member 角色
Steve 在项目 Alpha 上具有 admin 角色
鉴于上述分配和策略,以下是可能的
Alice 可以列出或检索特定的端点。Alice 不能执行任何项目特定的操作,因为她的授权仅限于部署系统。
Bob 可以检索特定的端点、列出它们并更新它们。他不能创建新的端点或删除现有的端点。Bob 不能执行任何项目特定的操作,因为他的授权仅限于部署系统。
Charlie 可以检索特定的端点、列出它们以及创建它们。此外,Charlie 可以列出有关迁移的信息以及超visor。他不能执行任何项目特定的操作,因为他的授权仅限于部署系统。
Qiana 可以列出所有标签并获取项目 Alpha 中特定标签的详细信息。她不能执行系统特定的策略,因为她的授权仅限于单个项目。
Rebecca 可以列出所有标签、获取特定标签的详细信息以及更新项目 Alpha 中的标签。她不能执行任何系统特定的策略,因为她的授权仅限于单个项目。
Steve 可以列出所有标签、创建新标签、获取特定标签的详细信息、更新标签以及删除项目 Alpha 中的标签。他不能执行任何系统特定的策略,因为他的授权仅限于单个项目。
风险缓解¶
场景一 – 存在一个服务于本规范中描述目的的角色,该角色在另一个名称下存在:假设部署 A 已经具有 Role X,它服务于此处提出的作为 reader 角色的目的。在这种情况下,可以合理地假设操作员可能具有自定义策略工作,并且不想立即移植。
可以通过使用隐式角色来缓解此问题。操作员只需要确保 reader 意味着 Role X。请查看有关 隐式角色的文档,以获取有关如何使一个角色意味着另一个角色的具体说明。
场景二 – 已经存在一个现有的 ``reader``、``member`` 或 ``admin`` 角色:假设部署 B 已经具有 member 角色。Keystone 不会尝试覆盖任何已填充的现有角色。它会在日志输出中注意到该名称为 member 的角色已经存在。但是,无论先前是否存在该角色,角色含义仍然会创建。
备选方案¶
reader/writer/admin 与 reader/member/admin。关于这些角色的命名约定进行了很多讨论。我们选择使用 reader、member 和 admin,因为我们认为在考虑 OpenStack 的上下文时,它们最准确地描述了它们的目的。
实现¶
负责人¶
主要负责人
Lance Bragstad lbragstad lbragstad@gmail.com
Harry Rybacki hrybacki hrybacki@redhat.com
工作项¶
添加 Keystone 引导程序创建所提议角色的能力
在策略中实施 reader 角色
在策略中实施 member 角色
在策略中实施 admin 角色
为 Keystone 中的所有策略实施 scope_types
删除 @protected 装饰器
记录操作员如何生成具有服务特定角色的策略文件
准备概念验证,以演示并促进 OpenStack 社区目标的接受,以推广其他服务的默认角色。
依赖项¶
这项工作依赖于以下内容
本规范中详细介绍的工作将由 oslo 和 keystone 中正在进行中的策略工作补充
实施 system-scope 在 keystone 中
实施 scope_types
完整的依赖项和相关工作可以在 策略路线图 中找到。
资源¶
以前的 尝试提供默认角色
注意
本作品采用知识共享署名 3.0 非移植许可协议授权。 http://creativecommons.org/licenses/by/3.0/legalcode