permission-model-change-guide

安装量: 37
排名: #19088

安装

npx skills add https://github.com/tencentblueking/bk-ci --skill permission-model-change-guide

IAM 权限中心资源类型接入最佳实践指南 概述

本指南基于 creative_stream 资源类型接入权限中心的实践经验总结,提供一套可复用的标准流程,帮助团队成员快速完成新资源类型的权限接入。

接入流程总览 ┌─────────────────────────────────────────────────────────────────────────────┐ │ IAM 资源类型接入流程 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │ │ │ 1.需求 │───▶│ 2.后端 │───▶│ 3.IAM │───▶│ 4.数据库配置 │ │ │ │ 分析 │ │ 枚举 │ │ 配置 │ │ (SQL 或 API 二选一) │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────────────────┘ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 5.国际化 │───▶│ 6.用户组 │───▶│ 7.验证 │ │ │ │ 配置 │ │ 配置 │ │ 测试 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ⚡ 推荐:使用 API 接口替代 SQL 脚本,更简单、更安全 │ │ │ └─────────────────────────────────────────────────────────────────────────────┘

第一步:需求分析与规划 1.1 确定资源类型信息 项目 说明 示例 资源类型 ID 全局唯一标识,使用 snake_case creative_stream 中文名称 用于 UI 显示 创作流 英文名称 用于 UI 显示和日志 Creative Stream 父资源 通常为 project project 1.2 确定权限操作列表

参考已有资源类型(如 pipeline)设计操作列表:

操作类型 命名规范 说明 关联资源类型 create {resource}_create 创建资源 project(特殊) list {resource}_list 列表查看 {resource} view {resource}_view 查看详情 {resource} edit {resource}_edit 编辑资源 {resource} delete {resource}_delete 删除资源 {resource} execute {resource}_execute 执行资源 {resource} manage {resource}_manage 权限管理 {resource} 其他 按需定义 如 download、share、archive {resource}

注意: create 操作的 related_resource_type 必须是 project,因为创建时资源还不存在。

1.3 设计权限依赖关系 project_visit (基础权限) │ ├── {resource}_create ──────────────────────────────┐ │ │ └── {resource}_list │ │ │ └── {resource}_view │ │ │ ├── {resource}_edit ────────────────┤ │ │ │ │ ├── {resource}_manage │ │ └── {resource}_archive │ │ │ ├── {resource}_delete │ ├── {resource}_execute │ ├── {resource}_download │ └── {resource}_share │

第二步:后端枚举定义 2.1 修改 AuthResourceType.kt

文件路径: src/backend/ci/core/common/common-auth/common-auth-api/src/main/kotlin/com/tencent/devops/common/auth/api/AuthResourceType.kt

enum class AuthResourceType(val value: String) { // ... 已有枚举 ...

PIPELINE_DEFAULT("pipeline"),
PIPELINE_GROUP("pipeline_group"),
PIPELINE_TEMPLATE("pipeline_template"),
CREATIVE_STREAM("creative_stream"),  // 新增:创作流类型

// ... 其他枚举 ...

}

命名规范:

枚举名:大写下划线 CREATIVE_STREAM value:小写下划线 creative_stream 第三步:IAM RBAC 配置文件

需要修改 support-files/bkiam-rbac/ 目录下的 5 个 JSON 文件:

3.1 资源类型定义 (0003_resource_*.json) { "operation": "upsert_resource_type", "data": { "id": "creative_stream", "name": "创作流", "name_en": "Creative Stream", "parents": [ { "system_id": "bk_ci_rbac", "id": "project" } ], "provider_config": { "path": "/api/open/auth/resource/instances/list?x-devops-project-id=rbac-project" }, "version": 1 } }

3.2 实例选择器 (0004_instance-views_*.json) { "operation": "upsert_instance_selection", "data": { "id": "creative_stream_instance", "name": "创作流", "name_en": "Creative Stream", "resource_type_chain": [ { "system_id": "bk_ci_rbac", "id": "project" }, { "system_id": "bk_ci_rbac", "id": "creative_stream" } ] } }

3.3 操作定义 (0005_action_*.json)

每个操作需要定义:

{ "operation": "upsert_action", "data": { "id": "creative_stream_view", "name": "查看创作流", "name_en": "Creative Stream View", "type": "view", "related_resource_types": [ { "system_id": "bk_ci_rbac", "id": "creative_stream", "selection_mode": "instance", "related_instance_selections": [ { "system_id": "bk_ci_rbac", "id": "creative_stream_instance" } ] } ], "related_actions": ["project_visit", "creative_stream_list"], "version": 1 } }

关键字段说明:

字段 说明 type 操作类型:view/edit/delete/create/execute related_resource_types 操作关联的资源类型 selection_mode 选择模式:instance(实例级)/ all(全部) related_actions 依赖的前置操作

create 操作的特殊配置:

{ "id": "creative_stream_create", "related_resource_types": [ { "system_id": "bk_ci_rbac", "id": "project", // 关联 project 而非 creative_stream "selection_mode": "instance", "related_instance_selections": [ { "system_id": "bk_ci_rbac", "id": "project_instance" } ] } ], "related_actions": ["project_visit"] }

3.4 权限分组 (0006_group_*.json)

将所有操作归入一个分组,便于 IAM 界面展示:

{ "operation": "upsert_action_groups", "data": { "action_groups": [ { "name": "创作流", "name_en": "Creative Stream", "actions": [ {"id": "creative_stream_create"}, {"id": "creative_stream_list"}, {"id": "creative_stream_view"}, {"id": "creative_stream_edit"}, {"id": "creative_stream_delete"}, {"id": "creative_stream_execute"}, {"id": "creative_stream_download"}, {"id": "creative_stream_share"}, {"id": "creative_stream_manage"}, {"id": "creative_stream_archive"} ] } ] } }

3.5 资源创建者关联操作 (0007_create-related_*.json)

定义创建资源后自动授予创建者的权限:

{ "id": "creative_stream", "actions": [ {"id": "creative_stream_list", "required": false}, {"id": "creative_stream_view", "required": false}, {"id": "creative_stream_edit", "required": false}, {"id": "creative_stream_delete", "required": false}, {"id": "creative_stream_execute", "required": false}, {"id": "creative_stream_download", "required": false}, {"id": "creative_stream_share", "required": false}, {"id": "creative_stream_manage", "required": false}, {"id": "creative_stream_archive", "required": false} ] }

第四步:数据库 DML 脚本 4.1 脚本类型与用途 脚本类型 文件位置 用途 是否必须 初始化脚本 support-files/sql/5001_init_dml/5001_ci_auth-init_dml_mysql.sql 开源社区部署时的数据初始化 ✅ 必须 增量脚本 openspec/changes/{change-id}/specs/auth-resource-type/xxx_dml.sql 内部线上已有数据的增量变更 内部使用 API 接口 /api/op/auth/resourceTypeConfig/* 内部线上已有数据的运行时变更 内部使用

重要:

初始化脚本是必须的,用于开源社区新部署时初始化权限数据 增量脚本和 API 接口二选一,用于内部线上环境的数据变更 4.2 表结构说明 表名 说明 T_AUTH_RESOURCE_TYPE 资源类型定义 T_AUTH_ACTION 操作定义 T_AUTH_RESOURCE_GROUP_CONFIG 用户组配置(资源级 + 项目级) 4.3 新增资源类型 REPLACE INTO T_AUTH_RESOURCE_TYPE ( ID, RESOURCE_TYPE, NAME, ENGLISH_NAME, DESC, ENGLISH_DESC, PARENT, SYSTEM, CREATE_USER, CREATE_TIME, UPDATE_USER, UPDATE_TIME, DELETE ) VALUES ( 22, -- 查询现有最大 ID + 1 'creative_stream', '创作流', 'Creative Stream', '创作流', 'Creative Stream', 'project', 'bk_ci_rbac', 'system', NOW(), 'system', NOW(), 0 );

4.4 新增操作定义 REPLACE INTO T_AUTH_ACTION( ACTION, RESOURCE_TYPE, RELATED_RESOURCE_TYPE, ACTION_NAME, ENGLISH_NAME, CREATE_USER, CREATE_TIME, UPDATE_TIME, DELETE, ACTION_TYPE ) VALUES ('creative_stream_view', 'creative_stream', 'creative_stream', '查看创作流', 'Creative Stream View', 'system', NOW(), NOW(), 0, 'view'), ('creative_stream_create', 'creative_stream', 'project', -- 注意:关联 project '创建创作流', 'Creative Stream Create', 'system', NOW(), NOW(), 0, 'create'), -- ... 其他操作 ;

4.5 新增资源级用户组

资源级用户组用于单个资源实例的权限管理:

-- 拥有者组 (全部权限) REPLACE INTO T_AUTH_RESOURCE_GROUP_CONFIG( ID, RESOURCE_TYPE, GROUP_CODE, GROUP_NAME, CREATE_MODE, GROUP_TYPE, DESCRIPTION, AUTHORIZATION_SCOPES, ACTIONS ) VALUES ( 70, -- 查询现有最大 ID + 1 'creative_stream', 'manager', '拥有者', 0, 0, '创作流拥有者,可以管理当前创作流的权限', '[授权范围 JSON]', '["creative_stream_view","creative_stream_edit",...]' );

资源级用户组标准配置:

组代码 组名 典型权限 manager 拥有者 全部权限(除 create) editor 编辑者 view + edit + execute + list + download + share executor 执行者 view + execute + list + download + share viewer 查看者 view + list + download + share 4.6 更新项目级用户组

为现有项目级用户组添加新资源的权限:

-- 使用 JSON_ARRAY_APPEND 追加权限 UPDATE T_AUTH_RESOURCE_GROUP_CONFIG SET AUTHORIZATION_SCOPES = JSON_ARRAY_APPEND( AUTHORIZATION_SCOPES, '$', JSON_OBJECT( 'system', '#system#', 'actions', JSON_ARRAY( JSON_OBJECT('id', 'creative_stream_list'), JSON_OBJECT('id', 'creative_stream_download'), JSON_OBJECT('id', 'creative_stream_share') ), 'resources', JSON_ARRAY( JSON_OBJECT( 'system', '#system#', 'type', 'creative_stream', 'paths', JSON_ARRAY( JSON_ARRAY( JSON_OBJECT('system', '#system#', 'type', 'project', 'id', '#projectId#', 'name', '#projectName#') ) ) ) ) ) ) WHERE ID = 2; -- developer 组

项目级用户组权限分配建议:

ID 组名 建议权限 1 管理员 (manager) create + 全部资源操作 2 开发人员 (developer) create + list + download + share 3 运维人员 (maintainer) create + list + download + share 4 产品人员 (pm) list 5 测试人员 (tester) create + list + download + share 6 质管人员 (qc) list 7 访客 (visitor) list 第五步:使用 API 接口配置数据(内部线上变更)

适用场景: 内部线上环境已有数据的增量变更,可替代增量 SQL 脚本,更简单、更安全、更不易出错。

注意: API 接口不能替代初始化脚本,初始化脚本用于开源社区新部署。

5.1 API 接口概览

接口路径: /api/op/auth/resourceTypeConfig

功能 方法 路径 说明 获取资源类型列表 GET /resourceTypes 查询所有资源类型 创建资源类型 POST /resourceTypes 新增资源类型 获取操作列表 GET /actions 查询操作定义 批量创建操作 POST /actions/batch 批量新增操作 获取用户组配置 GET /groupConfigs 查询用户组配置 批量创建用户组 POST /groupConfigs/batch 批量新增资源级用户组 追加新权限块 PUT /groupConfigs/{id}/appendActions 新增一个完整的资源类型权限块 追加到已有块 PUT /groupConfigs/{id}/appendActionsToExistingScope 在已有权限块的 actions 中追加 智能追加 PUT /groupConfigs/{id}/smartAppendActions 自动判断:存在则追加,不存在则新建 批量追加(新建块) POST /groupConfigs/batchAppendActions 批量新增权限块 批量智能追加 POST /groupConfigs/batchSmartAppendActions 批量自动判断追加方式 一键创建完整配置 POST /resourceTypes/full 一次性创建资源类型+操作+用户组 5.2 追加 Actions 的三种方式 方式一:追加新权限块(appendActions)

适用场景:为用户组添加一个全新资源类型的权限

在 AUTHORIZATION_SCOPES 数组末尾新增一个完整的权限块

curl -X PUT \ "http://devops.example.com/api/op/auth/resourceTypeConfig/groupConfigs/1/appendActions\ ?resourceType=creative_stream" \ -H "Content-Type: application/json" \ -d '["creative_stream_create", "creative_stream_list"]'

方式二:追加到已有权限块(appendActionsToExistingScope)⭐

适用场景:某个资源类型的权限块已存在,只需要在其 actions 数组中追加新的 action

在已有的 project 权限块的 actions 数组中追加 creative_stream_create

curl -X PUT \ "http://devops.example.com/api/op/auth/resourceTypeConfig/groupConfigs/1/\ appendActionsToExistingScope?targetResourceType=project" \ -H "Content-Type: application/json" \ -d '["creative_stream_create"]'

示例效果:

// 修改前 { "system": "#system#", "actions": [{"id": "project_visit"}, {"id": "project_edit"}], "resources": [{"type": "project", ...}] }

// 修改后(追加了 creative_stream_create) { "system": "#system#", "actions": [ {"id": "project_visit"}, {"id": "project_edit"}, {"id": "creative_stream_create"} ], "resources": [{"type": "project", ...}] }

方式三:智能追加(smartAppendActions)⭐⭐

适用场景:不确定权限块是否存在,让系统自动判断

如果目标资源类型的权限块已存在 → 追加到该块的 actions 中 如果不存在 → 创建新的权限块

智能追加:系统自动判断是追加到已有块还是新建块

curl -X PUT \ "http://devops.example.com/api/op/auth/resourceTypeConfig/groupConfigs/1/\ smartAppendActions?resourceType=project" \ -H "Content-Type: application/json" \ -d '["creative_stream_create"]'

5.3 批量操作示例 5.3.1 创建资源类型 curl -X POST "http://devops.example.com/api/op/auth/resourceTypeConfig/resourceTypes" \ -H "Content-Type: application/json" \ -d '{ "resourceType": "creative_stream", "name": "创作流", "englishName": "Creative Stream", "desc": "创作流", "englishDesc": "Creative Stream", "parent": "project", "system": "bk_ci_rbac" }'

5.3.2 批量创建操作 curl -X POST "http://devops.example.com/api/op/auth/resourceTypeConfig/actions/batch" \ -H "Content-Type: application/json" \ -d '[ { "action": "creative_stream_create", "resourceType": "creative_stream", "relatedResourceType": "project", "actionName": "创建创作流", "englishName": "Creative Stream Create", "actionType": "create" }, { "action": "creative_stream_list", "resourceType": "creative_stream", "relatedResourceType": "creative_stream", "actionName": "创作流列表", "englishName": "Creative Stream List", "actionType": "list" }, { "action": "creative_stream_view", "resourceType": "creative_stream", "relatedResourceType": "creative_stream", "actionName": "查看创作流", "englishName": "Creative Stream View", "actionType": "view" } ]'

5.3.3 批量创建资源级用户组 curl -X POST \ "http://devops.example.com/api/op/auth/resourceTypeConfig/groupConfigs/batch" \ -H "Content-Type: application/json" \ -d '[ { "resourceType": "creative_stream", "groupCode": "manager", "groupName": "拥有者", "description": "创作流拥有者,可以管理当前创作流的权限", "createMode": false, "groupType": 0, "actions": [ "creative_stream_view", "creative_stream_edit", "creative_stream_delete", "creative_stream_execute", "creative_stream_download", "creative_stream_share", "creative_stream_manage", "creative_stream_archive" ], "authorizationScopes": "[授权范围JSON]" }, { "resourceType": "creative_stream", "groupCode": "editor", "groupName": "编辑者", "description": "创作流编辑者", "createMode": false, "groupType": 0, "actions": [ "creative_stream_view", "creative_stream_edit", "creative_stream_execute", "creative_stream_download", "creative_stream_share" ], "authorizationScopes": "[授权范围JSON]" } ]'

5.3.4 批量智能追加到项目级用户组

使用 batchSmartAppendActions:自动判断追加方式

curl -X POST \ "http://devops.example.com/api/op/auth/resourceTypeConfig/groupConfigs/batchSmartAppendActions" \ -H "Content-Type: application/json" \ -d '[ { "groupConfigId": 1, "resourceType": "project", "actions": ["creative_stream_create"] }, { "groupConfigId": 2, "resourceType": "project", "actions": ["creative_stream_create"] }, { "groupConfigId": 7, "resourceType": "creative_stream", "actions": ["creative_stream_list"] } ]'

说明:

ID 1、2 的 project 权限块已存在,会在其 actions 中追加 creative_stream_create ID 7 的 creative_stream 权限块不存在,会新建一个权限块 5.4 API vs 增量 SQL 脚本对比

注意: 以下对比仅针对内部线上环境的增量变更,不涉及初始化脚本。

维度 API 接口 增量 SQL 脚本 易用性 简单,无需了解表结构 需熟悉表结构和 JSON 格式 ID 管理 自动分配,无冲突风险 需手动查询并分配 幂等性 接口内置处理 需使用 REPLACE INTO 验证 接口层参数校验 无校验,易出错 事务 自动事务管理 需手动管理 适用场景 内部线上运行时配置 内部线上版本升级 5.5 请求/响应 DTO 说明 ResourceTypeCreateRequest data class ResourceTypeCreateRequest( val resourceType: String, // 资源类型代码 val name: String, // 中文名称 val englishName: String, // 英文名称 val desc: String? = null, // 中文描述 val englishDesc: String? = null, // 英文描述 val parent: String? = "project", // 父资源类型 val system: String? = "bk_ci_rbac" // 系统标识 )

ActionCreateRequest data class ActionCreateRequest( val action: String, // 操作代码 val resourceType: String, // 所属资源类型 val relatedResourceType: String, // 关联资源类型(create 操作为 project) val actionName: String, // 中文名称 val englishName: String, // 英文名称 val actionType: String // 操作类型:create/list/view/edit/delete/execute )

ResourceGroupConfigCreateRequest data class ResourceGroupConfigCreateRequest( val resourceType: String, // 资源类型 val groupCode: String, // 组代码 val groupName: String, // 组名称 val description: String? = null, // 描述 val createMode: Boolean = false, // 创建模式 val groupType: Int = 0, // 组类型 val actions: List, // 操作列表 val authorizationScopes: String? = null // 授权范围 JSON )

ProjectGroupConfigUpdateRequest data class ProjectGroupConfigUpdateRequest( val groupConfigId: Long, // 项目级用户组配置 ID (1-7) val resourceType: String, // 资源类型 val actions: List // 要追加的操作列表 )

第六步:国际化配置 6.1 文件位置

support-files/i18n/auth/ 目录下的三个文件:

message_zh_CN.properties (中文) message_en_US.properties (英文) message_ja_JP.properties (日文) 6.2 配置内容

资源类型

creative_stream.resourceType.name=创作流 creative_stream.resourceType.desc=创作流

操作名称

creative_stream_create.actionName=创建创作流 creative_stream_list.actionName=创作流列表 creative_stream_view.actionName=查看创作流 creative_stream_edit.actionName=编辑创作流 creative_stream_delete.actionName=删除创作流 creative_stream_execute.actionName=执行创作流 creative_stream_download.actionName=下载创作流制品 creative_stream_share.actionName=分享创作流制品 creative_stream_manage.actionName=创作流权限管理 creative_stream_archive.actionName=归档创作流

资源级用户组

creative_stream.manager.authResourceGroupConfig.groupName=拥有者 creative_stream.manager.authResourceGroupConfig.description=创作流拥有者,可以管理当前创作流的权限 creative_stream.editor.authResourceGroupConfig.groupName=编辑者 creative_stream.editor.authResourceGroupConfig.description=创作流编辑者,拥有当前创作流除了权限管理之外的所有权限 creative_stream.executor.authResourceGroupConfig.groupName=执行者 creative_stream.executor.authResourceGroupConfig.description=创作流执行者,可以查看和执行创作流,下载或分享制品 creative_stream.viewer.authResourceGroupConfig.groupName=查看者 creative_stream.viewer.authResourceGroupConfig.description=创作流查看者,可以查看创作流,下载或分享制品

第七步:同步初始化脚本(必须) 7.1 更新 5001_ci_auth-init_dml_mysql.sql

这是必须步骤,初始化脚本用于开源社区新部署时的数据初始化。

将变更内容同步到初始化脚本,使用 REPLACE INTO 语法确保幂等性。

注意事项:

初始化脚本使用完整的 JSON 字符串,不使用 JSON_ARRAY_APPEND 确保 ID 不与现有数据冲突 使用 REPLACE INTO 而非 INSERT 保证幂等 必须同步所有变更,包括: 新增资源类型 新增操作定义 新增资源级用户组 更新项目级用户组(直接修改完整 JSON) 第八步:验证清单 8.1 文件修改清单 文件 修改内容 是否必须 AuthResourceType.kt 新增枚举值 ✅ 必须 0003_resource_.json 新增资源类型 ✅ 必须 0004_instance-views_.json 新增实例选择器 ✅ 必须 0005_action_.json 新增所有操作定义 ✅ 必须 0006_group_.json 新增权限分组 ✅ 必须 0007_create-related_*.json 新增创建者关联操作 ✅ 必须 message_zh_CN.properties 中文国际化 ✅ 必须 message_en_US.properties 英文国际化 ✅ 必须 message_ja_JP.properties 日文国际化 ✅ 必须 5001_ci_auth-init_dml_mysql.sql 开源社区部署初始化数据 ✅ 必须 增量 SQL 脚本 内部线上增量变更 内部使用(与 API 二选一) 8.2 验证要点 资源类型 ID 全局唯一 操作 ID 命名规范:{resource}_{action} create 操作关联 project 资源类型 所有操作都有正确的 related_actions 依赖 用户组 ID 不与现有数据冲突(使用 API 自动处理) 三语国际化配置完整 项目级所有用户组(ID 1-7)都已更新 资源级用户组权限矩阵合理 8.3 API 接口验证

使用 API 接口配置后,可通过以下接口验证:

验证资源类型

curl "http://devops.example.com/api/op/auth/resourceTypeConfig/resourceTypes/creative_stream"

验证操作列表

curl "http://devops.example.com/api/op/auth/resourceTypeConfig/actions?resourceType=creative_stream"

验证用户组配置

curl \ "http://devops.example.com/api/op/auth/resourceTypeConfig/groupConfigs?resourceType=creative_stream"

常见问题与解决方案 Q1: 如何确定新资源类型的 ID?

查询现有最大 ID:

SELECT MAX(ID) FROM T_AUTH_RESOURCE_TYPE; SELECT MAX(ID) FROM T_AUTH_RESOURCE_GROUP_CONFIG;

Q2: 权限依赖关系如何设计?

遵循最小权限原则:

view 依赖 list edit/delete/execute 依赖 view manage 依赖 edit 所有操作依赖 project_visit Q3: 为什么 create 操作关联 project?

因为创建资源时,资源实例还不存在,无法基于资源实例授权,所以需要基于项目授权。

Q4: AUTHORIZATION_SCOPES JSON 结构? [ { "system": "#system#", "actions": [{"id": "action_id"}], "resources": [ { "system": "#system#", "type": "resource_type", "paths": [[ {"system": "#system#", "type": "project", "id": "#projectId#", "name": "#projectName#"}, {"system": "#system#", "type": "resource_type", "id": "#resourceCode#", "name": "#resourceName#"} ]] } ] } ]

参考资料 蓝鲸权限中心文档 已有资源类型实现:pipeline、credential、environment 等 本次 creative_stream 接入归档:openspec/changes/archive/2025-12-16-add-creative-stream-resource-type/

返回排行榜