Barbican 密钥删除支持

https://blueprints.launchpad.net/glance/+spec/barbican-secret-deletion-support

块存储服务 (Cinder) 允许最终用户从加密卷类型创建镜像。当它这样做时,Cinder 会在 Barbican 中存储一个密钥,与镜像之间存在 1-1 的关系,并将 Barbican 密钥的 ID 作为镜像属性,cinder_encryption_key_id。当用户删除此类镜像时,Barbican 密钥不再适用于任何资源,但它仍然存在于 Barbican 中。因此,部署者面临的情况是无用的密钥在 Barbican 中不断累积。如果在镜像删除时 Glance 删除镜像的唯一 Barbican 密钥,就可以缓解这个问题。

问题描述

Cinder 希望 Glance 删除 Glance 未创建的资源(Barbican 密钥)。鉴于大多数部署允许用户设置自定义镜像属性,因此用户可以将 cinder_encryption_key_id 元数据放在任何镜像上,这可能导致过早删除正在使用的密钥,因为 Barbican 密钥 ID 与 Glance 镜像之间的 1-1 关系已被破坏。因此,Glance 不愿意实现可能导致最终用户数据丢失的功能。

提议的变更

添加 Glance 通用镜像属性 cinder_encryption_key_deletion_policy。此时,cinder_encryption_key_id 也会被添加为通用镜像属性。由于通用镜像属性存储在 image_properties 表中,因此它们必须具有 string 类型的 JSON。作为通用镜像属性,它们将按照以下方式添加到默认 schema-image.json 文件中

{
    "cinder_encryption_key_id": {
       "description": "Identifier in the OpenStack Key Management Service for the encryption key for the Block Storage Service to use when mounting a volume created from this image",
       "type": "string"
    },
    "cinder_encryption_key_deletion_policy": {
        "description": "States the condition under which the Image Service will delete the object associated with the 'cinder_encryption_key_id' image property.  If this property is missing, the Image Service will take no action",
        "type": "string",
        "enum": [
            "on_image_deletion",
            "do_not_delete"
        ]
    }
}

注意

注意:通用镜像属性是互操作性建议,但不是 Glance 的强制功能。因此,不能保证特定的 Glance 安装允许在镜像模式响应中列出它们。因此,我们不能依赖于此属性值的模式验证。请注意,这不会影响 Cinder 将这些属性写入镜像(只要 Glance 配置选项 allow_additional_image_properties 为 True,而这是其默认值)。

注意

我们应该认真考虑在本周期内弃用 allow_additional_image_properties 配置选项。我相信它最初是为了防止用户用垃圾数据淹没 image_properties 表而引入的,并且早于 image_property_quota 选项。现在我们有了后者选项,它实际上是不必要的,如果操作员将其设置为 False,各种东西都会损坏,因为多个 OpenStack 服务当前会写入/依赖于自定义镜像属性。

注意

有人在 IRC 中问过我一个错误(我无法在 Launchpad 中找到它,可能没有提交),操作员可以修改 /etc/schema-image.json 以包含任意属性(这是该文件的原始目的)并为它们分配除“string”以外的其他 JSON 类型。类型由镜像创建/更新强制执行,但你会得到一个 500 错误,因为它必须是数据库中的字符串(但如果模式表示它是布尔值或其他类型,API 不会接受字符串)。我们应该记录这些内容必须是字符串。

此属性的存在及其适当的值赋予 Glance 删除密钥的明确权限,即使 Glance 未创建它。当此属性存在于镜像上且值为“on_image_deletion”时,Glance 将搜索镜像的属性以查找属性 cinder_encryption_key_id。如果存在,Glance 将向 Barbican 发出请求以删除 ID 为镜像属性值的密钥。

由于 cinder_encryption_key_deletion_policy 是一个自定义镜像属性,因此可以由镜像所有者添加/删除/更新。因此,如果镜像所有者有理由保留密钥,可以通过将值更改为“do_not_delete”或简单地删除 cinder_encryption_key_deletion_policy 属性来撤销删除权限。

错误条件

  • 如果镜像上不存在 cinder_encryption_key_id,则镜像删除不会受到 delete_encryption_key_on_image_deletion: on_image_deletion 的影响。

  • 如果 cinder_encryption_key_id 指示一个不存在的 Barbican ID,则应将其记录下来,但不会影响镜像删除。

  • 如果 cinder_encryption_key_deletion_policy 的值不是 on_image_deletiondo_not_delete,Glance 将执行以下操作

    • 不采取任何操作,关于 cinder_encryption_key_id

    • 删除镜像

备选方案

  1. 什么也不做,让最终用户显式地从 Barbican 删除密钥。这对于 Cinder 工作流程来说是一个问题,Cinder 工作流程将密钥管理隐藏在用户面前,因此用户可能在镜像删除(及其元数据消失)后一段时间才意识到 Barbican 密钥可以删除,并且密钥 ID 也不可用了。由于不可能知道任何密钥是否有任何内容正在引用它,用户无法简单地转到 Barbican 并确定哪些密钥不再使用。因此,这并不是一个可行的替代方案。

  2. cinder_encryption_key_id 作为唯一的元数据,并使其存在足以让 Glance 在镜像删除时删除密钥。这有一个缺点,即以非标准方式使用 Cinder 功能的最终用户无法阻止 Glance 删除可能仍在使用的 Barbican 密钥。

  3. 不要将 cinder_encryption_key_deletion_policy 作为通用镜像属性,而是让它成为一个常规的自定义镜像属性,类似于 Nova 调度器识别的自定义镜像属性。由于自动密钥删除带来的数据丢失可能性,最好在镜像模式中清楚地记录其功能,而不是仅依赖于文档。

  4. cinder_encryption_key_deletion_policy 设为布尔值而不是枚举字符串类型。不幸的是,它实际上不能是布尔类型,因为它必须存储为字符串,这对于工具开发人员来说很令人困惑,因为它的值将是 "true",而不是 JSON true 值。此外,包含

    cinder_encryption_key_deletion_policy: on_image_deletion
    

    关于此镜像属性的含义是自我记录的。

数据模型影响

无。通用镜像属性出现在镜像模式中,但存储在 image_properties 表中,与自定义镜像属性一起存储。

REST API 影响

无。

安全影响

对 Glance 的安全性没有影响。可以说,这使得 Cinder-Glance 卷到镜像的功能更加安全。它不再让用户处于清理 Barbican 中大量多余密钥的境地,其中一个密钥可能实际上正在使用。此外,它不需要用户手动删除密钥(用户可能会删除错误的密钥)。

通知影响

无。

其他最终用户影响

Cinder 工作流程旨在将密钥处理隐藏在用户面前;这与该设计一致。

性能影响

Glance 需要在镜像删除过程中向 Barbican 发出调用。

其他部署者影响

这将是对部署者的奖励,他们不再需要担心无用的 Barbican 密钥不断累积。

开发人员影响

无。

实现

负责人

主要负责人

brian-rosmaita 或 abhishek-kekane

工作项

  1. 修改镜像模式以包含新的通用镜像属性,并使 Cinder 当前使用的属性 cinder_encryption_key_id 成为官方的通用镜像属性。

  2. 实现代码以在镜像删除时删除 Barbican 中的密钥。

依赖项

无。

测试

由于我们感兴趣的场景是 Glance 是否可以在某些条件下从 Barbican 删除密钥,可以实现一个 tempest 测试,该测试创建一个密钥,将适当的元数据放在镜像上,删除镜像并验证 Barbican 密钥是否/是否未被删除。

如果存在实际在 Glance 中创建加密卷镜像的现有 tempest 测试,那么我们可以 piggyback 在该测试上以验证密钥删除是否发生。当然,这必须等到 Cinder 实施将新的 cinder_encryption_key_deletion_policy 标志放在从加密卷创建的镜像上。

文档影响

记录新的属性以及其余的通用镜像属性。

参考资料