策略库

包含您的 Launchpad 蓝图的 URL

https://blueprints.launchpad.net/congress/+spec/policy-library

当 Congress 首次部署时,它不会执行任何监控或强制执行,因为没有指定任何策略。在 Congress 提供任何价值之前,学习策略语言并编写所需的策略需要投入大量的时间和精力。

问题描述

为了帮助部署者和管理员快速上手并看到价值,我们建议在 Congress 中包含一个有用的策略库,部署者或管理员可以轻松地启用、禁用和自定义该库。

提议的变更

概述

拟议的更改包含两个主要部分:新的策略库和对现有 Congress 服务器功能进行的更改,以支持使用策略库中的策略。

策略库

在 Congress 服务器中引入策略库的新概念,策略库用于保留和操作策略,但不用于策略引擎(用于监控或强制执行)。在 Congress 服务器中包含一个有用的策略集合,每个策略都在一个 YAML 文件中。这些策略会自动填充策略库。

为了方便我们填充库,并方便管理员修改/创建自己的库,API/CLI/GUI 应该支持对库进行完全的 CRUD 操作。

  • Congress 服务器可以有一个新的配置选项,指向一个包含要加载到库中的策略的目录。

    • 从文件中初始化库后,重启 Congress 服务器不会重新从文件中初始化策略库(假定空库是未初始化的)。一个新的接口允许管理员触发从文件重新初始化。

      注意

      策略库存储在数据库中,并且在 Congress 服务器中独立于策略库目录中的文件而存在。另请参阅替代模型的讨论 策略库目录文件作为真理

    • 未来功能:自动重新加载库中更改的文件

      • 不会更新从库导入到策略引擎中的策略

      • 开放问题:通过 API 对策略库进行的更改是否应该同步回策略库目录中的文件?

      • 必须小心考虑并发更改以及来自多个 congress 服务器实例的潜在冲突。

警告

当 Congress 服务器策略引擎服务被复制时,不同的服务器实例必须具有相同的策略库文件。否则,库将基于不同服务器实例上的策略文件的任意组合进行填充。

  • 安装

    • 独立部署:安装脚本将默认库目录从 Congress git 仓库复制到 /etc/congress/。

    • Devstack:与独立部署相同

支持使用库中的策略

我们建议添加所有必需的功能,以支持以下工作流程,用于从策略库激活策略(即,通过从策略库导入(非活动)策略,在策略引擎中创建(活动)策略)。

  • 使用 CLI/API 从库激活策略。

    1. 管理员检查库中的策略以找到他们想要使用的策略。

    2. 管理员下载相关的策略,以 YAML 或 JSON 格式。

    3. 管理员修改 YAML/JSON 编码,并将其用作创建新策略的有效负载。

  • 使用 GUI 从库激活策略。

    1. 管理员浏览库中的策略

    2. 管理员单击一个有趣的策略,这将弹出一个文本框(或更复杂的策略编辑器)进行自定义。

    3. 管理员单击“创建”按钮,该按钮创建该策略。

以下是支持这些工作流程所需的特定功能。

  • 对 policies POST API 进行向后兼容的更改,以允许在 JSON/YAML 有效负载主体中包含“rules”键。

  • 一个新的可选参数添加到 policy create CLI 命令中,允许管理员从 YAML 文件导入并激活策略。

  • 一个新的可选参数添加到 policy create CLI 命令中,允许管理员直接从策略库导入并激活策略,而无需保存到文件。

    注意

    策略引擎规则插入代码需要进行一些仔细的重构,以确保使用规则创建策略是事务性的。也就是说,如果在第三条规则处插入失败(例如,由于跨策略递归),则前两条规则的插入将被撤消,而不会产生任何影响(触发的操作或更改的查询答案)。

    需要三个主要事项。

    • 仅在所有策略规则在策略引擎中成功插入后,才写入数据库。

    • 必须延迟触发评估,直到所有规则都成功插入为止。

    • 必须防止策略引擎在处理一批规则插入时回答查询。这可以通过锁或确保执行批量规则插入的 greenthread 不会产生来实现。

  • Horizon GUI 中的新页面,管理员可以在其中执行以下任务。

    • 浏览和检查策略库中的策略

    • 激活(即,导入到策略引擎)来自策略库的策略

    • 在导入之前自定义策略库中的策略

备选方案

本节讨论了针对此提案的各个方面的几种替代设计和实现。

策略库严格外部于 Congress

  • API/数据模型中没有库的概念。策略库只是管理员可以导入到策略引擎中的文件目录。

    • 开发工作量最少。

    • 不太可用。管理员无法使用现有的 Congress 界面(CLI/GUI/API)来浏览、检查、自定义和激活策略库中的策略。

    • 此版本通过 spec 中提出的更改的子集来实现。应该优先开发这个子集,以实现此处描述的最小可行功能。

策略库目录文件作为真理

  • 不使用数据库,而是使用策略库目录中的策略文件作为真理来源。

    • 在具有多个策略引擎的设置中,复杂且容易出错。

    • 与 Congress 服务器中的所有其他持久化数据模型不同,增加了开发人员的复杂性。

库规则作为策略引擎中相同数据库表中的禁用规则

  • 与其在单独的逻辑存储库以及与规则引擎中的活动规则不同的数据库表中存储库中的规则,不如将所有规则作为规则引擎中的规则存储,并添加一个额外的标志指示哪些规则是活动的。

    • 使策略引擎中的规则现有数据模型复杂化。

    • 有什么好处?

策略

不适用。

策略动作

不适用

数据源

不适用。

数据模型影响

对现有表没有影响。

需要一个新的数据库表

  • 一个 library_policies 表用于存储策略库中的策略。以下是列。

    • name = sa.Column(sa.String(255), nullable=False, unique=True, primary_key=True)

    • abbreviation = sa.Column(sa.String(5), nullable=False)

    • description = sa.Column(sa.Text(), nullable=False)

    • kind = sa.Column(sa.Text(), nullable=False)

    • rules = sa.Column(sa.Text(), nullable=False)

    注意

    由于库中的规则以整个策略的粒度访问,因此我们可以通过将规则存储为文本块而不是单独的行来提高简单性和性能。

    警告

    TEXT 类型在 MySQL 中长度限制为 2^16 - 1 字节。不支持超过此大小的非常大的策略。如果此限制过于严格,可以通过在 SQL Alchemy 列声明中指定更长的长度来强制使用 MEDIUMTEXT 或 LONGTEXT 类型,但代价是失去 SQLite 支持(主要用于单元测试)。

将使用 sqlalchemy 迁移脚本创建空表。Congress 服务器将从策略库文件夹中的策略文件填充表。

REST API 影响

策略库方法

  • 重新初始化

    • 从配置中设置的策略库目录中的文件中重新初始化策略库。

    警告

    此操作将销毁策略库的当前内容。

    • 方法类型:PUT

    • 正常的 http 响应代码:200

    • 预期的 http 响应代码:401

    • /v1/library

    • 可以通过 url 传递的参数:无

    • 如果允许,主体数据的 JSON 模式定义:不允许

    • 如果有任何响应数据,则 JSON 模式定义:无

  • 列出策略

    • 列出库中所有策略的元数据(id、名称、描述、规则数)

    • 方法类型:GET

    • 正常的 http 响应代码:200

    • 预期的错误 http 响应代码:无

    • /v1/library

    • 可以通过 url 传递的参数:无

    • 如果允许,主体数据的 JSON 模式定义:不允许

    • 如果存在,则为响应数据定义 JSON schema

      - !Type:
        title: collection of PolicyProperties
        type: array
        items:
          type: object
          properties:
            name:
              title: Policy unique name
              type: string
              required: true
            description:
              title: Policy description
              type: string
              required: true
            kind:
              title: Policy kind
              type: string
              required: true
            abbreviation:
              title: Policy name abbreviation
              type: string
              required: false
      
  • 显示策略

    • 显示指定的库策略(以指定的格式)

    • 方法类型:GET

    • 正常的 http 响应代码:200

    • 预期的 http 响应代码:401、404

    • /v1/library/<policy-name>

    • 可以通过 url 传递的参数:无

    • 如果允许,主体数据的 JSON 模式定义:不允许

    • 如果有任何响应数据,则 JSON 模式定义:策略完整模式

  • 创建策略

    • 在库中创建一个新策略

    • 方法类型:POST

    • 正常的 http 响应代码:200

    • 预期的 http 响应代码:400、401、409

    • /v1/library

    • 可以通过 url 传递的参数:无

    • 如果允许,主体数据的 JSON 模式定义:策略完整模式

    • 如果有任何响应数据,则 JSON 模式定义:没有 UUID 的策略元数据模式

  • 更新策略

    • 更新库中的策略

    • 方法类型:PUT

    • 正常的 http 响应代码:200

    • 预期的 http 响应代码:400、401、404、409

    • /v1/library/<policy-name>

    • 可以通过 url 传递的参数

      • 格式:{json, yaml}(默认值为 json)

    • 如果允许,主体数据的 JSON 模式定义:策略完整模式

    • 如果有任何响应数据,则 JSON 模式定义:没有 UUID 的策略元数据模式

  • 删除策略

    • 从库中删除策略

    • 方法类型: DELETE

    • 正常的 http 响应代码:200

    • 预期的 http 响应代码:401、404

    • /v1/library/<policy-name>

    • 可以通过 url 传递的参数:无

    • 如果允许,主体数据的 JSON 模式定义:不允许

    • 如果有任何响应数据,则 JSON 模式定义:无

策略引擎方法

  • 创建策略

    • 在策略引擎中创建一个策略(来自输入数据或来自库)

    • 方法类型:POST

    • 正常的 http 响应代码:200

    • 预期的 http 响应代码:400、401、404、409

    • /v1/policies

    • 可以通过 url 传递的参数

      • library_policy=<库中策略的名称>。这直接从库策略创建策略,而无需主体数据。如果同时指定了此参数和主体数据,则应返回错误 400。

    • 如果允许,主体数据的 JSON 模式定义:策略完整模式

    • 如果有任何响应数据,则 JSON 模式定义:带有 UUID 的策略元数据模式

常用 JSON 模式

没有 UUID 的策略元数据模式
- !Type:
  id: PolicyProperties
  title: Policy Properties
  type: object
  properties:
    name:
      title: Policy unique name
      type: string
      required: true
    description:
      title: Policy description
      type: string
      required: true
    kind:
      title: Policy kind
      type: string
      required: true
    abbreviation:
      title: Policy name abbreviation
      type: string
      required: false

注意

策略库中的策略不使用 UUID。原因是,如果策略被激活,UUID 更改会让人困惑,但如果在策略引擎中保留激活策略中的 UUID,则会导致两个不同的实体共享相同的 UUID,这也会有问题。

带有 UUID 的策略元数据模式
- !Type:
  id: PolicyProperties
  title: Policy Properties
  type: object
  properties:
    id:
      title: UUID for the policy
      type: string
      required: true
    name:
      title: Policy unique name
      type: string
      required: true
    description:
      title: Policy description
      type: string
      required: false
    kind:
      title: Policy kind
      type: string
      required: false
    abbreviation:
      title: Policy name abbreviation
      type: string
      required: false
策略完整模式

注意

一个设计决策是,策略库中的规则没有 ID 并且不能单独引用。库中的策略是在整个策略的级别创建、更新或删除的。

- !Type:
  id: PolicyProperties
  title: Policy Properties
  type: object
  properties:
    name:
      title: Policy unique name
      type: string
      required: true
    description:
      title: Policy description
      type: string
      required: true
    kind:
      title: Policy kind
      type: string
      required: true
    abbreviation:
      title: Policy name abbreviation
      type: string
      required: false
    rules:
      title: collection of rules
      type: array
      required: true
      items:
        type: object
        properties:
          id: PolicyRule
          title: Policy rule
          type: object
          properties:
            rule:
              title: Rule definition following policy grammar
              type: string
              required: true
            name:
              title: User-friendly name
              type: string
              required: false
            comment:
              title: User-friendly comment
              type: string
              required: false

安全影响

通常,预计不会产生重大的安全影响。但是,以下是一些安全注意事项。

  • 如果策略库更改同步回服务器上的策略库目录,那么获得 Congress 管理员权限的攻击者也可以创建和修改 Congress 服务器的策略库目录中的文件。

  • 在策略创建 API 中提交多个规则可能会增加资源耗尽攻击的潜力。

通知影响

无影响

其他最终用户影响

对现有工作流程没有影响。

性能影响

预计性能影响最小。必须小心避免自动检测策略库文件夹中的更改并相应地更新策略库所带来的性能影响。

其他部署者影响

对部署者没有负面影响。

  • 没有更改现有的数据库表模式。

  • 将使用新的数据库表,这些表将通过 alembic 迁移脚本添加。

开发者影响

开发人员影响最小。

实现

负责人

将在 launchpad 上分配。

工作项

将在 launchpad 上组织。

依赖项

没有新的依赖项。

测试

除了单元测试外,对 congress_tempest_tests/tests/scenarios/test_congress_basic_ops.py 中的测试的直接添加就足够了。

文档影响

影响最小。

参考资料

没有参考资料。