The policy.json file¶
警告
虽然旧的 json 格式策略文件仍然受支持,但我们建议使用较新的 YAML 格式。
每个 OpenStack 服务,包括 Identity、Compute、Networking 等,都有其自己的基于角色的访问策略。它们决定了哪个用户可以以哪种方式访问哪些对象,并在服务的 policy.json 文件中定义。
每当对 OpenStack 服务进行 API 调用时,服务的策略引擎都会使用适当的策略定义来确定是否可以接受该调用。对 policy.json 的任何更改都会立即生效,这允许在服务运行时实施新策略。
一个 policy.json 文件是一个 JSON(Javascript 对象表示法)格式的文本文件。每个策略由形式为 "<target>" : "<rule>" 的单行语句定义。
策略目标,也称为“action”,代表一个 API 调用,例如“启动实例”或“附加卷”。
Action 名称通常是限定的。例如,Compute 服务具有用于列出实例、卷和网络的 API 调用。在 /etc/nova/policy.json 中,这些 API 分别由 compute:get_all、volume:get_all 和 network:get_all 表示。
API 调用和 action 之间的映射通常没有文档记录。
策略规则确定在什么情况下允许 API 调用。通常,这涉及发出调用的用户(以下称为“API 用户”)以及 API 调用所操作的对象。典型的规则检查 API 用户是否是对象的拥有者。
警告
修改策略
虽然可以在博客上找到编辑 policy.json 文件的配方,但修改策略可能会产生意想不到的副作用,并且不鼓励这样做。
示例¶
一个简单的规则可能如下所示
"compute:get_all" : ""
目标是 "compute:get_all",Compute 服务的“列出所有实例”API。规则是一个空字符串,意思是“总是”。此策略允许任何人列出实例。
您也可以拒绝使用 API 的权限
"compute:shelve": "!"
感叹号代表“永不”或“没有人”,有效地禁用了 Compute API“shelve an instance”。
许多 API 只能由管理员调用。这可以通过规则 "role:admin" 来表示。以下策略确保只有管理员才能在 Identity 数据库中创建新用户
"identity:create_user" : "role:admin"
注意
admin 是 Keystone 中的一个内置默认角色。有关更多详细信息和其他可用角色,请参阅 Keystone 关于默认角色的文档。
您可以将 API 限制为任何角色。例如,Orchestration 服务定义了一个名为 heat_stack_user 的角色。拥有此角色的任何人都不允许创建堆栈
"stacks:create": "not role:heat_stack_user"
此规则使用了布尔运算符 not。可以使用运算符 and、or 和括号构建更复杂的规则。
您可以为规则定义别名
"deny_stack_user": "not role:heat_stack_user"
策略引擎理解 "deny_stack_user" 不是 API,因此将其解释为别名。上面的堆栈创建策略可以写成
"stacks:create": "rule:deny_stack_user"
这直接取自 /etc/heat/policy.json。
规则可以将 API 属性与对象属性进行比较。例如
"os_compute_api:servers:start" : "project_id:%(project_id)s"
指出只有实例的拥有者才能启动它。冒号前的 project_id 字符串是一个 API 属性,即 API 用户的项目 ID。它与对象的项目 ID 进行比较(在本例中,是一个实例)。更确切地说,它与数据库中该对象的 project_id 字段进行比较。如果这两个值相等,则授予权限。
管理员始终有权调用 API。这就是 /etc/keystone/policy.json 明确制定此策略的方式
"admin_required": "role:admin or is_admin:1",
"owner" : "user_id:%(user_id)s",
"admin_or_owner": "rule:admin_required or rule:owner",
"identity:change_password": "rule:admin_or_owner"
第一行定义了“用户是管理员用户”的别名。is_admin 标志仅在首次设置 Identity 服务时使用。它指示用户具有服务令牌授予的管理员权限(keystone 命令行客户端的 --os-token 参数)。
第二行通过比较 API 的用户 ID 与对象的用户 ID 创建了一个“用户拥有对象”的别名。
第 3 行定义了第三个别名 admin_or_owner,使用布尔运算符 or 组合了前两个别名。
第 4 行设置了策略,即密码只能由其所有者或管理员用户修改。
作为最后的例子,让我们检查一个更复杂的规则
"identity:ec2_delete_credential": "rule:admin_required or
(rule:owner and user_id:%(target.credential.user_id)s)"
此规则确定谁可以使用 Identity API“删除 EC2 凭证”。在这里,布尔运算符和括号组合了三个简单的规则。admin_required 和 owner 与前一个示例中的别名相同。user_id:%(target.credential.user_id)s 将 API 用户与与目标关联的凭证对象的用户 ID 进行比较。
语法¶
一个 policy.json 文件由形式为 target:rule 或 alias:definition 的策略和别名组成,用逗号分隔并包含在花括号中
{
"alias 1" : "definition 1",
"alias 2" : "definition 2",
...
"target 1" : "rule 1",
"target 2" : "rule 2",
....
}
Targets 是 API,写成 "service:API" 或简单地 "API"。例如,"compute:create" 或 "add_image"。
规则确定是否允许 API 调用。
规则可以是
始终为真。该操作始终被允许。这可以写成
""(空字符串)、[]或"@"。始终为假。该操作从不被允许。写成
"!"。一个特殊的检查
两个值的比较
基于更简单的规则的布尔表达式
特殊检查是
role:<role name>,测试 API 凭证是否包含此角色。rule:<rule name>,别名的定义。http:<target URL>,将检查委托给远程服务器。如果服务器返回 True,则授权 API。
开发人员可以定义额外的特殊检查。
以以下方式比较两个值
"value1 : value2"
可能的值是
常量:字符串、数字、
true、falseAPI 属性
目标对象属性
标志
is_admin
API 属性可以是 project_id、user_id 或 domain_id。
目标对象属性是数据库中对象描述中的字段。例如,在 "compute:start" API 的情况下,对象是要启动的实例。启动实例的策略可以使用 %(project_id)s 属性,即拥有该实例的项目。尾随的 s 表示这是一个字符串。
is_admin 指示通过 admin token 机制(keystone 命令行客户端的 --os-token 选项)授予管理员权限。admin token 允许在 admin 角色存在之前初始化 Identity 数据库。
别名构造存在于方便起见。别名是复杂或难以理解的规则的简短名称。它以与策略相同的方式定义
alias name : alias definition
定义别名后,使用 rule 关键字在策略规则中使用它。
旧语法¶
您可能会遇到具有不同语法的较旧的 policy.json 文件,其中使用 JavaScript 数组代替布尔运算符。例如,上面的 EC2 凭证规则将如下所示
"identity:ec2_delete_credential": [ [ "rule:admin_required ],
[ "rule:owner", "user_id:%(target.credential.user_id)s)" ] ]
该规则是一个数组的数组。最内层的数组是或在一起的,而最内层数组中的元素是与在一起的。
虽然旧语法仍然受支持,但我们建议使用更新、更直观的语法。