Harbor 复制模块权限验证:项目管理员对复制规则与作业的只读权限测试解析
【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor
导读
本文以 Harbor 仓库测试用例 7-11-Project-admin-readonly.md 为核心,说明该用例的验证目的、运行环境、执行步骤与预期结果,并结合 Harbor 源码(RBAC 权限资源模型、v2.0 复制 API 的系统级鉴权实现、Portal 前端按钮级权限控制)剖析"项目管理员(Project Admin)对复制规则(Replication Rule)和复制作业(Replication Job)仅拥有只读权限"背后的权限设计原理。读完本文,你将理解 Harbor 中复制功能为何被设计为系统级能力、项目管理员在项目内复制页签下能做什么与不能做什么,以及如何通过源码与测试用例双重确认这一行为。
1. 测试用例背景与验证目的
复制(Replication)是 Harbor 实现多云、多实例间制品分发与同步的核心能力:管理员配置复制规则,将制品从源实例复制到目标实例,并可通过手动、定时或事件驱动方式触发执行,同时可查看执行作业与日志。
测试用例 7-11 的Purpose非常明确:
To verify project admin user has read-only privilege for replication rules and jobs.
即:验证项目管理员用户对复制规则和复制作业仅拥有只读权限。换言之,项目管理员虽然对项目内的制品、标签、成员、扫描等拥有管理能力,但在复制(Replication)这一功能域内,其角色被收敛为"只能查看、不能变更",这正是 Harbor 将复制定位为系统级功能的具体体现。
2. 环境与前置条件
用例 7-11-Project-admin-readonly.md 对环境提出了四项明确要求:
| # | 前置条件 | 说明 |
|---|---|---|
| 1 | 至少两台 Harbor 实例正在运行且可用 | 复制是跨实例操作,需要源实例与目标实例 |
| 2 | 至少创建一条复制规则 | 作为只读验证的对象之一 |
| 3 | 该复制规则至少产生一个复制作业 | 验证规则与作业两类对象均只读;作业可通过手动触发等方式产生(参见同目录 7-05-Trigger-manual.md、7-06-Trigger-immediate.md、7-07-Trigger-scheduled.md) |
| 4 | 已将一名成员以admin角色添加到该复制规则所应用的项目中 | 该成员即"项目管理员",是本次测试的被测用户 |
其中第 4 点强调"admin 角色"指的是项目角色中的管理员(Project Admin),而非 Harbor 系统管理员(System Admin)——后者拥有全部系统级权限,不属于本用例的验证对象。
3. 执行步骤与预期结果
用例给出的操作路径极短,只有两步:
- 使用项目管理员用户登录 Harbor UI;
- 进入
Projects -> Project_Name -> Replication页面(即项目详情下的"复制"页签)。
预期结果(Expected Outcome):
在步骤 2 中,该用户应对所有复制规则和复制作业拥有只读权限。
具体到 UI 行为,即:项目管理员可以查看规则列表、查看作业列表、查看作业日志,但不应看到新建/编辑/删除规则、手动执行(Run Now)等写操作入口;即使通过 API 直接调用写接口,也会被后端鉴权拦截。该用例标记"Possible Problems: None",说明在正常实现下不存在已知的边界问题。
4. 源码级原理剖析:只读权限从何而来
上述"只读"行为并非前端单纯的按钮隐藏,而是由后端 RBAC 权限模型与 API 层鉴权共同保证的。以下逐一梳理。
4.1 RBAC 资源与动作模型
Harbor 在 src/common/rbac/const.go 中定义了权限评估所需的资源(Resource)与动作(Action)常量:
- 动作(L22-L38):
ActionCreate、ActionRead、ActionUpdate、ActionDelete、ActionList等,与 RESTful API 方法一一对应; - 复制相关资源(L73-L77):
ResourceReplication = Resource("replication"):复制执行/作业类资源;ResourceReplicationAdapter = Resource("replication-adapter"):复制适配器;ResourceReplicationPolicy = Resource("replication-policy"):复制规则(策略)资源。
权限策略在PoliciesMap(L164-L315)中按作用域组织:
- 系统作用域 ScopeSystem下(L177-L187)明确授予了复制相关全部读写权限:
ResourceReplicationPolicy:Read / Create / Delete / List / Update;ResourceReplication:Read / Create / List;ResourceReplicationAdapter:List。
- 项目作用域 ScopeProject下(L236-L313)完全没有任何 replication 相关条目——项目作用域只覆盖日志、项目配置、仓库、制品、扫描、标签、配额、保留策略、不可变标签等。
这是第一个关键证据:复制权限只存在于系统作用域,与项目作用域无关。
4.2 项目角色权限映射:projectAdmin 不包含复制写权限
项目内成员角色在 src/common/rbac/project/rbac_role.go 的rolePoliciesMap(L23)中定义,共四类:projectAdmin、maintainer、developer、guest。
其中projectAdmin角色(L25-L120)拥有项目内最广泛的权限,包括:成员管理(member)、元数据(metadata)、日志查看(log)、标签(label)、仓库(repository 的 create/read/update/delete/pull/push)、标签保留策略(tag-retention)、不可变标签(immutable-tag)、机器人账户(robot)、通知策略(notification-policy)、扫描(scan)、制品(artifact)、标签(tag)、P2P 预热策略(preheat-policy)、CVE 导出(export-cve)等。
但通读projectAdmin的完整策略列表可以发现:其中没有任何一条ResourceReplicationPolicy或ResourceReplication条目。这意味着即便在项目命名空间内评估项目管理员的权限,复制规则与复制作业也不在其授权范围内。
4.3 replication API 全部走系统级鉴权
第二层保障来自 API 层。v2.0 的复制功能由 src/server/v2.0/handler/replication.go 中的replicationAPI实现,其中每一个复制相关接口都通过RequireSystemAccess进行鉴权:
| API 方法 | 鉴权调用 | 源码位置 |
|---|---|---|
CreateReplicationPolicy(新建规则) | RequireSystemAccess(ctx, ActionCreate, ResourceReplicationPolicy) | L53-L54 |
UpdateReplicationPolicy(编辑规则) | RequireSystemAccess(ctx, ActionUpdate, ResourceReplicationPolicy) | L132-L133 |
ListReplicationPolicies(规则列表) | RequireSystemAccess(ctx, ActionList, ResourceReplicationPolicy) | L206-L207 |
GetReplicationPolicy(规则详情) | RequireSystemAccess(ctx, ActionRead, ResourceReplicationPolicy) | L237-L238 |
DeleteReplicationPolicy(删除规则) | RequireSystemAccess(ctx, ActionDelete, ResourceReplicationPolicy) | L248-L249 |
StartReplication(启动复制) | RequireSystemAccess(ctx, ActionCreate, ResourceReplication) | L258-L259 |
StopReplication(停止复制) | RequireSystemAccess(ctx, ActionCreate, ResourceReplication) | L282-L283 |
ListReplicationExecutions(执行列表) | RequireSystemAccess(ctx, ActionList, ResourceReplication) | L292-L293 |
GetReplicationExecution(执行详情) | RequireSystemAccess(ctx, ActionRead, ResourceReplication) | L354-L355 |
ListReplicationTasks(任务列表) | RequireSystemAccess(ctx, ActionList, ResourceReplication) | L365-L366 |
GetReplicationLog(作业日志) | RequireSystemAccess(ctx, ActionRead, ResourceReplication) | L425 附近 |
RequireSystemAccess的实现位于 src/server/v2.0/handler/base.go:从安全上下文取当前用户,未认证返回UnauthorizedError,若无法在系统命名空间(system.NewNamespace())内满足指定动作与资源的权限,则返回ForbiddenError。
因此可以确认:复制规则与复制作业的所有读写接口都是系统级资源接口。项目管理员不是系统管理员,在系统命名空间内没有复制资源的任何授权,故其对规则的创建、编辑、删除以及复制的启动、停止都会被拒绝;而项目作用域内本就没有复制资源策略,RequireProjectAccess路径同样无法放行写操作。这正是用例所验证的"只读"的硬性保障——即使绕过 UI 直接调用 API 也无法越权。
4.4 前端按钮级权限控制
Portal 侧同样做了权限收敛。复制组件hbr-replication(replication.component.ts)通过四个布尔输入控制操作能力:
@Input() hasCreateReplicationPermission: boolean; @Input() hasUpdateReplicationPermission: boolean; @Input() hasDeleteReplicationPermission: boolean; @Input() hasExecuteReplicationPermission: boolean;这些标志被透传给规则列表组件 list-replication-rule.component.ts,并驱动模板 list-replication-rule.component.html 中"新建""执行"等按钮的显隐(@if (hasCreateReplicationPermission)、@if (hasExecuteReplicationPermission))。
系统级"复制管理"页面(total-replication-page.component.html)为系统管理员视图,将四个权限标志全部硬编码为true。而项目详情下的 Replication 页签复用同一组件,从代码结构可以推断:项目级页面传入的权限标志根据当前用户在复制资源上的实际授权计算得出;由于项目管理员在项目作用域内不拥有任何复制资源策略,这些标志均为false,从而在 UI 上表现为"只读"——仅能查看规则、作业与日志。前端隐藏按钮 + 后端RequireSystemAccess拒绝的双重机制,保证了只读语义无法被绕过。
5. 用例在复制测试矩阵中的位置
本用例是 Harbor 复制功能测试矩阵(tests/testcases/Group7-Replication)的一员,该目录下共 16 个用例,覆盖复制功能的完整行为面:
- 规则生命周期:7-01 添加规则、7-02 编辑规则、7-03 删除规则、7-04 规则过滤;
- 触发方式:7-05 手动触发、7-06 立即触发、7-07 定时触发;
- 作业与过滤:7-08 作业过滤、7-09 作业日志查看、7-10 过滤;
- 权限边界:本文的 7-11 项目管理员只读;
- 远端仓库(Endpoint/Registry)管理:7-12 添加端点、7-13 编辑端点、7-14 删除端点、7-15 端点过滤、7-16 按端点 CA 证书管理。
7-11 与 7-12~7-16 共同勾勒出复制的权限边界:规则、作业、远端仓库的增删改均属系统级操作,项目管理员仅可查看。
6. 验证要点与结论
结合用例步骤与源码证据,执行本用例时可从三个层面确认只读行为:
- UI 层面:以项目管理员登录后进入
Projects -> 项目名 -> Replication,规则列表与作业列表可见、作业日志可查看,但新建/编辑/删除规则、手动执行等入口不可见; - API 层面:用项目管理员的会话直接调用
POST /api/v2.0/replication/policies等写接口,应收到 403Forbidden(src/server/v2.0/handler/replication.go),证明只读由后端强制保证; - 权限模型层面:复制资源仅存在于系统作用域(src/common/rbac/const.go),项目管理员角色策略中无任何复制条目(src/common/rbac/project/rbac_role.go)。
结论:Harbor 将复制规则与复制作业定位为系统级资源,项目管理员对它们天然只有查看权限。该设计避免了项目级成员误改影响全局的复制配置,是多实例同步场景下重要的权限安全边界。理解这一模型,有助于在规划 Harbor 权限体系时正确区分"系统管理员"与"项目管理员"的职责范围,并为自动化测试或二次开发中的权限断言提供依据。
相关仓库路径速查
- 测试用例:tests/testcases/Group7-Replication/7-11-Project-admin-readonly.md
- RBAC 资源与策略定义:src/common/rbac/const.go
- 项目角色权限映射:src/common/rbac/project/rbac_role.go
- 复制 API 鉴权实现:src/server/v2.0/handler/replication.go
- 系统级鉴权工具:src/server/v2.0/handler/base.go
- 前端权限按钮控制:list-replication-rule.component.ts、total-replication-page.component.html
【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考