ShortTermAuthZinNova
Nova 中的短期授权
问题
授权是指提出问题“<用户> 能否对 <某个资源> <执行某事>?” 例如,“[Sandy] 能否 [删除实例] [病毒感染的服务器]?”
Keystone 是 Nova 的官方授权系统。为了提供上述功能,Keystone 使用一些特殊的抽象概念
- 角色 - 具有相似工作职能的用户组。角色是分组这些用户的一种方式。这样,我们不必明确声明 Bob、Mary 和 Alice 可以控制 Financial 服务器,我们可以说 Bob、Mary 和 Alice 具有 Finance 角色。
- 能力 - 能力是授权中的 <执行某事> 部分。用户可以在 <资源> 上执行哪些操作?Nova、Swift 等所有服务都将有一组标准、商定的能力,以及每个服务添加自己能力的权限。
最后是角色和能力到资源的映射。这将提供授权正常运行所需的所有数据模型。
一旦我们采用 Zones,问题就变得复杂了。在这种情况下,授权系统中定义的模型需要应用于跨多个 Nova 安装的资源。更复杂的是联合部署模型,在这种模型中,客户拥有自己的 Nova 部署,并希望“爆发”到使用服务提供商的 Nova 部署。这些需求记录在此处:https://wiki.openstack.org/FederatedAuthZwithZones
好消息是,已经有计划将所有这些功能添加到 Keystone(到目前为止,Keystone 一直专注于 AuthN)。坏消息是,在 Keystone 实现准备好之前,我们可能需要在 Nova 中实现一些原始的授权功能。
本页将提出一种在短期内获得 Nova 中粗略授权支持的方法。
我们希望在 Essex 设计峰会上讨论这个问题和本页中提出的步骤 http://summit.openstack.org/sessions/view/80
Keystone 授权路线图
Keystone 将在 Essex 设计峰会上举行会议,讨论他们的授权计划 https://wiki.openstack.org/keystone 并计划在 2011 年 11 月中旬批准这些计划。
简而言之,计划的推出将分三个阶段进行
- 阶段 1 - 空角色:https://wiki.openstack.org/AuthZ%20-%20Empty%20Roles
- 阶段 2 - 显式能力映射:https://wiki.openstack.org/AuthZ%20-%20Explicit%20Capability%20Mapping
- 阶段 3 - 受限角色:https://wiki.openstack.org/AuthZ%20-%20Restricted%20Roles
在第一阶段,将添加空角色。空角色是没有能力的角色。我们将能够将用户与角色关联起来,但无法说明这些角色可以做什么。在第二阶段,角色将具有能力。但这些能力不适用于任何给定的资源。在第三阶段,角色、能力、资源集合将完成。此时,我们的临时授权工作可能会从 Nova 中删除,并由 Keystone 替换。
技术层面的问题
资源管理
Nova 中授权的最终目标是 Nova 不必担心角色或用户-资源映射。相反,我们只需要将资源映射到角色。Keystone 管理员应处理将能力分配给这些角色以及哪些用户具有这些角色。为什么?因为当我们进入联合部署和多区域部署时,我们不能假定可以访问外部授权系统中包含的角色或用户信息。我们只有“<令牌> 可以对 <资源 UUID> <执行某事>”的元组……其余的都将对我们隐藏。我们越早采用这种心态,将来对我们来说就越容易。
但是,让我们考虑一下我们所说的资源是什么意思。自然假设是资源是 Nova 管理的某种实体。明显的资源是实例、网络和卷。但是,从实际层面来看,如果我们必须针对添加到或从环境中删除的每个实例、网络或卷都返回到 Keystone,Keystone 将会非常繁忙。
相反,我们需要能够将这些资源分组到资源组中。Nova 可以毫不费力地将实例添加到或从这些资源组中删除,而无需使 Keystone 负担过重。Keystone 可以处理将角色分配给资源组(或者在绝对必要时分配给较低级别的资源,因为它们实际上只是系统中的 UUID)。
任务:向 Nova 添加资源组
我们需要添加管理(和管理 API?)支持资源组的 CRUD 操作。目前尚不清楚这些资源组是否需要是同质的或异质的,但我假设是异质的,因为我们可能希望将网络、实例和卷捆绑到一个组中以进行控制。
任务:将这些资源组告知授权系统
授权系统无法管理它不知道的东西。当添加/删除资源组时,我们需要通知授权系统,以便管理员可以建立关系。
能力强制执行
一旦我们将资源组与令牌的映射到位,在某个时候,我们需要确定当前的令牌是否可以对所请求的资源 <执行某事>。
问题是,谁执行此检查?Nova 是否应该缓存与当前令牌关联的所有令牌到资源映射?可能不是,如果列表很大。Nova 是否应该查询回授权系统以询问“<令牌> 能否对 <资源> <执行此操作>?”……那很好,但会有时间和网络成本。
任务:创建一个(内存中?)服务,我们可以查询以进行授权检查
将来,这将由 Keystone 替换……理想情况下,具有一些缓存以使其高效。
接下来,这些权限检查应该在哪里发生?让我们快速回顾一下 Nova 的流程
我们可以在三个地方进行这些检查
- 在公共 API 层(这意味着我们需要在 OS API 和 EC2 API 中放置检查)
- 在服务 API 层。常见的会议是所有操作,但在实际工作完成之前。
- 在服务本身中。橡胶与道路相遇的地方。
我个人认为 #2 服务 API 层是正确的位置。
我们可以通过装饰器执行检查,但是很难将资源 ID 放入装饰器中,因为在我们深入函数之前,我们可能不知道目标资源是什么。所以我觉得装饰器行不通。这意味着在服务 API 方法中进行显式函数调用到授权服务。
self.authz.check_can_delete(context, resource)
如果未获得许可,将引发异常
任务:编写这个授权强制执行类
稍后,这个类将把操作委托给 Keystone,但现在它将自己完成工作。
任务:确定核心能力集应该是什么
任务:将这个授权类添加到服务 API 的适当位置
任务:添加一个异常处理程序,以提供有意义的错误消息(可能不需要?)
配置
最后,我们需要某种数据存储来保存此临时授权数据。这不需要花哨,因为所有这些都将被替换。我们不需要使用 nova-manage 更改进行所有类型的数据库模式更新等。
考虑某种 .conf / .py 或 .json 文件,其中包含资源组 -> 用户/令牌 -> 能力的基本关系。
问题是,这是否是静态数据,更改时可能需要关闭依赖服务?或者我们可以使其自动检测文件更改并按需重新加载?也许有点过头了?

