将目标传递给 Glance 的策略执行器

https://blueprints.launchpad.net/glance/+spec/pass-targets-to-policy-enforcer

目前,可以在 Glance 的 policy.json 中定义自定义规则,这些规则依赖于用户角色以外的属性。不幸的是,如果您尝试应用其中一条规则,它将始终导致用户被阻止执行相关操作。本规范建议我们将适当的目标对象传递给执行器,以便可以使用这些规则并正确执行它们。

问题描述

目前,Glance 承诺可以在 policy.json 文件中配置权限,但任何非角色检查的规则当前都会导致 403 Forbidden 响应。由于这是一个承诺的功能,因此实施本规范只是在修复已经承诺的行为。

在 Glance 的 policy.json 中,无法根据用户角色以外的任何内容来限制对操作的访问。Glance 扩展的 oslo 策略执行器期望将类似字典的对象作为操作的目标传递。当前使用策略执行器并执行相应操作定义的策略的每个方法都会传递一个空字典 ({}),这几乎不提供关于实际目标的任何数据。

如果我们定义一个类似于以下规则

"tenant_is_owner": "tenant%(owner)s"

并且将其应用于一个操作,例如:

"delete_image": "rule:tenant_is_owner"

那么每次删除任何镜像的请求都会被 Glance 的 API 以 403(禁止)响应拒绝。原因在于规则的解析方式以及目标的传递方式。"rule:tenant_is_owner" 规则将被解析为 GenericCheck。这些检查以 : 分隔为 kindmatch(大致上,"<kind>:<match>")。然后,匹配部分与目标进行插值,即:

match = self.match % target

因此,使用上面的示例,我们将执行

match = "%(owner)s" % {}

但是,这会引发 KeyError,这意味着检查会立即返回 False 并失败。在这种特定情况下(删除镜像),如果我们传递 glance.api.policy.ImageTarget 的实例,那么会发生的是插值会成功。

提议的变更

对于基于镜像的资源,解决方案很简单。我们在与镜像相关的策略代理中拥有 image。我们只需将其传递给 glance.api.policy.ImageTarget 并传递结果实例给策略执行器,以便在插值时可以将其作为字典访问。对于成员和任务,我们没有可以使用目标类。这些是非常薄的类,可以很容易地编写。

一旦我们有了适当定义的 target 类,我们就会更新策略执行的位置,以使用这些 target 类的实例。

有了适当的目标后,我们还可以为仅依赖默认 policy.json 文件的操作员实施更安全的默认策略规则。

备选方案

可以禁用基于目标对象属性的自定义规则创建。这将严重限制操作员根据用户租户和其他操作目标属性来限制操作的能力。

数据模型影响

REST API 影响

安全影响

这将赋予操作员对其 Glance 安装的安全性的显著控制权。目前他们只能根据角色来限制操作,这在某些情况下可能就足够了。但是,如果操作员希望根据其他因素(除了角色)来限制访问,他们就无法做到这一点。如果他们尝试这样做,则不会表明它不起作用,但他们基本上会向应该能够基于定义的策略执行操作的用户产生拒绝服务。

通知影响

其他最终用户影响

性能影响

其他部署者影响

要利用此规范中的修复程序,操作员需要更新其部署中使用的 policy.json 版本。要编写规则,操作员需要知道 glance 提供三个值,这些值可以在冒号 (:) 的左侧的规则中使用。这些值是当前用户的凭据形式:

  • 角色

  • tenant

  • owner

冒号的左侧还可以包含 Python 可以理解的任何值,例如:

  • True

  • False

  • "a string"

  • &c。

角色检查将继续像以前一样工作。如果检查中定义的角色是用户持有的角色,那么它将通过,例如 role:admin

使用 tenantowner 仅适用于镜像或与镜像交互的操作。考虑以下规则

tenant:%(owner)s

这将使用当前经过身份验证用户的 tenant 值。它还将使用它正在操作的镜像的 owner。如果这两个值相等,则检查将通过。镜像上的所有属性(以及额外的镜像属性)都可用于在冒号的右侧使用。最有用的如下:

  • owner

  • protected

  • is_public

因此,操作员可以构造如下规则集

{
    "not_protected": "False:%(protected)s",
    "is_owner": "tenant:%(owner)s",
    "not_protected_and_is_owner": "rule:not_protected and rule:is_owner",
    "delete_image": "rule:not_protected_and_is_owner"
}

开发人员影响

实现

负责人

主要负责人

icordasc

评审人员

核心评审人

nikhil-komawar jokke

其他审核员

kragniz

工作项

  • 创建适当的目标类

  • 使用目标类将目标代理到策略执行器

  • 添加测试,演示通用检查现在有效

  • 为现有的文档添加更好的策略规则文档

依赖项

测试

将在加载特定的 policy.json 文件以测试不同目标的访问控制的地方添加功能测试。

文档影响

没有直接影响,但现有的 policy.json 文档很薄,并且仅描述了每个规则控制的内容。它没有描述可用的目标信息或如何编写规则。

参考资料

相关 bug

初始实现工作

2015 年 1 月 15 日的 Glance 会议讨论