第 7 章 Red Hat Developer Hub 中的条件策略
Red Hat Developer Hub 中的权限框架提供了由 RBAC 后端插件支持的条件(backstage-plugin-rbac-backend
)。条件作为 RBAC 后端插件提供的 Developer Hub 资源的内容过滤器。
RBAC 后端 API 存储分配给数据库中的角色的条件。当您请求访问 frontend 资源时,RBAC 后端 API 会搜索对应的条件,并使用其插件 ID 将它们委派给适当的插件。如果您分配到具有不同条件的多个角色,则 RBAC 后端将使用 anyOf
条件合并条件。
- 条件条件条件
Developer Hub 中的条件是带有规则和参数的简单条件。但是,条件也可以包含参数或按条件条件组合的参数数组。支持的条件条件包括:
-
allOf
: 确保阵列中的所有条件都必须为 true,才能满足组合条件。 -
anyOf
: 确保该阵列中至少需要满足组合条件的条件。 -
Not : 确保其中的条件不能满足组合条件。
-
- 条件对象
该插件指定条件支持的参数。您可以从 RBAC API 端点访问条件对象模式,以了解如何构建条件 JSON 对象,然后由 RBAC 后端插件 API 使用该对象。
条件对象包含以下参数:
表 7.1. 条件对象参数 参数 类型 描述 result
字符串
始终值为
CONDITIONAL
roleEntityRef
字符串
对 RBAC 角色的字符串实体引用,如
role:default/dev
pluginId
字符串
对应的插件 ID,如
目录
permissionMapping
字符串数组
数组权限操作,如
['read', 'update', 'delete']
resourceType
字符串
插件提供的资源类型,如
catalog-entity
conditions
JSON
带有参数或数组参数的条件 JSON,按条件加入
- 条件策略别名
RBAC 后端插件(
backstage-plugin-rbac-backend
)支持在条件策略规则参数中使用别名。在策略评估过程中,条件策略别名会动态地替换为对应的值。条件策略中的每个别名都以$
符号作为前缀,代表其特殊功能。支持的条件别名包括:
-
$current
user:此别名替换为请求访问资源的用户的用户实体引用。例如,如果用户从默认命名空间请求访问,$currentUser
将变为user:default/tom
。
-
带有 $currentUser
别名的条件策略对象示例
{ "result": "CONDITIONAL", "roleEntityRef": "role:default/developer", "pluginId": "catalog", "resourceType": "catalog-entity", "permissionMapping": ["delete"], "conditions": { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["$currentUser"] } } }
-
$ownerRefs
:此别名替换为所有权引用,通常是作为包含用户实体引用和用户的父组实体引用的数组。例如,对于来自 team-a 的用户 Tom,$ownerRefs
将变为['user:default/tom', 'group:default/team-a']
。
带有 $ownerRefs
别名的条件策略对象示例
{ "result": "CONDITIONAL", "roleEntityRef": "role:default/developer", "pluginId": "catalog", "resourceType": "catalog-entity", "permissionMapping": ["delete"], "conditions": { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["$ownerRefs"] } } }
7.1. 条件策略参考
您可以访问 Red Hat Developer Hub 中条件策略的 API 端点。例如,要检索可用的条件规则,这有助于定义这些策略,您可以访问 GET [api/plugins/condition-rules]
端点。
api/plugins/condition-rules
返回条件参数 schemas,例如:
[ { "pluginId": "catalog", "rules": [ { "name": "HAS_ANNOTATION", "description": "Allow entities with the specified annotation", "resourceType": "catalog-entity", "paramsSchema": { "type": "object", "properties": { "annotation": { "type": "string", "description": "Name of the annotation to match on" }, "value": { "type": "string", "description": "Value of the annotation to match on" } }, "required": [ "annotation" ], "additionalProperties": false, "$schema": "http://json-schema.org/draft-07/schema#" } }, { "name": "HAS_LABEL", "description": "Allow entities with the specified label", "resourceType": "catalog-entity", "paramsSchema": { "type": "object", "properties": { "label": { "type": "string", "description": "Name of the label to match on" } }, "required": [ "label" ], "additionalProperties": false, "$schema": "http://json-schema.org/draft-07/schema#" } }, { "name": "HAS_METADATA", "description": "Allow entities with the specified metadata subfield", "resourceType": "catalog-entity", "paramsSchema": { "type": "object", "properties": { "key": { "type": "string", "description": "Property within the entities metadata to match on" }, "value": { "type": "string", "description": "Value of the given property to match on" } }, "required": [ "key" ], "additionalProperties": false, "$schema": "http://json-schema.org/draft-07/schema#" } }, { "name": "HAS_SPEC", "description": "Allow entities with the specified spec subfield", "resourceType": "catalog-entity", "paramsSchema": { "type": "object", "properties": { "key": { "type": "string", "description": "Property within the entities spec to match on" }, "value": { "type": "string", "description": "Value of the given property to match on" } }, "required": [ "key" ], "additionalProperties": false, "$schema": "http://json-schema.org/draft-07/schema#" } }, { "name": "IS_ENTITY_KIND", "description": "Allow entities matching a specified kind", "resourceType": "catalog-entity", "paramsSchema": { "type": "object", "properties": { "kinds": { "type": "array", "items": { "type": "string" }, "description": "List of kinds to match at least one of" } }, "required": [ "kinds" ], "additionalProperties": false, "$schema": "http://json-schema.org/draft-07/schema#" } }, { "name": "IS_ENTITY_OWNER", "description": "Allow entities owned by a specified claim", "resourceType": "catalog-entity", "paramsSchema": { "type": "object", "properties": { "claims": { "type": "array", "items": { "type": "string" }, "description": "List of claims to match at least one on within ownedBy" } }, "required": [ "claims" ], "additionalProperties": false, "$schema": "http://json-schema.org/draft-07/schema#" } } ] } ... <another plugin condition parameter schemas> ]
RBAC 后端 API 根据前面的条件模式构造一个条件 JSON 对象。
7.1.1. 条件策略示例
在 Red Hat Developer Hub 中,您可以使用或没有条件定义条件策略。您可以使用以下示例根据您的用例定义条件:
- 没有条件的条件
只有用户是所有者组的成员时,请考虑没有条件显示目录的条件。要添加此条件,您可以使用目录插件模式
IS_ENTITY_OWNER
,如下所示:没有条件的示例
{ "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["group:default/team-a"] } }
在上例中,唯一使用的条件参数是
claims
,其中包含用户或组实体引用的列表。您可以通过添加额外的参数将前面的示例条件应用到 RBAC REST API,如下所示:
{ "result": "CONDITIONAL", "roleEntityRef": "role:default/test", "pluginId": "catalog", "resourceType": "catalog-entity", "permissionMapping": ["read"], "conditions": { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["group:default/team-a"] } } }
- 具有条件的条件
考虑条件条件,它只有在用户是所有者组成员或显示所有目录用户组的列表时才会显示目录。
要添加条件,您可以在条件中添加另一个规则作为
IS_ENTITY_KIND
,如下所示:带有条件的条件示例
{ "anyOf": [ { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["group:default/team-a"] } }, { "rule": "IS_ENTITY_KIND", "resourceType": "catalog-entity", "params": { "kinds": ["Group"] } } ] }
注意不支持在创建过程中运行并行条件。因此,请考虑根据可用的标准定义嵌套条件策略。
嵌套条件示例
{ "anyOf": [ { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["group:default/team-a"] } }, { "rule": "IS_ENTITY_KIND", "resourceType": "catalog-entity", "params": { "kinds": ["Group"] } } ], "not": { "rule": "IS_ENTITY_KIND", "resourceType": "catalog-entity", "params": { "kinds": ["Api"] } } }
您可以通过添加额外的参数将前面的示例条件应用到 RBAC REST API,如下所示:
{ "result": "CONDITIONAL", "roleEntityRef": "role:default/test", "pluginId": "catalog", "resourceType": "catalog-entity", "permissionMapping": ["read"], "conditions": { "anyOf": [ { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["group:default/team-a"] } }, { "rule": "IS_ENTITY_KIND", "resourceType": "catalog-entity", "params": { "kinds": ["Group"] } } ] } }
以下示例可用于 Developer Hub 插件。这些示例可帮助您确定如何定义条件策略:
为 Keycloak 插件定义的条件策略
{ "result": "CONDITIONAL", "roleEntityRef": "role:default/developer", "pluginId": "catalog", "resourceType": "catalog-entity", "permissionMapping": ["update", "delete"], "conditions": { "not": { "rule": "HAS_ANNOTATION", "resourceType": "catalog-entity", "params": { "annotation": "keycloak.org/realm", "value": "<YOUR_REALM>" } } } }
前面的 Keycloak 插件示例可防止 role:default/developer
中的用户更新或删除在 Keycloak 插件中放入目录的用户。
在上例中,注解 keycloak.org/realm
需要 < YOUR_REALM
> 的值。
为 Quay 插件定义的条件策略
{ "result": "CONDITIONAL", "roleEntityRef": "role:default/developer", "pluginId": "scaffolder", "resourceType": "scaffolder-action", "permissionMapping": ["use"], "conditions": { "not": { "rule": "HAS_ACTION_ID", "resourceType": "scaffolder-action", "params": { "actionId": "quay:create-repository" } } } }
前面的 Quay 插件示例可防止角色 role:default/developer
使用 Quay builder 操作。请注意,permissionMapping
包含使用 ,表示
scaffolder-action
资源类型权限没有权限策略。
有关 Red Hat Developer Hub 中权限的更多信息,请参阅 第 6 章 权限策略参考。