Harbor多租户隔离以Project为边界,非用户或用户组;权限仅限Project级,不支持Repository/Tag级控制,角色固定五档且不继承叠加。

Harbor 多租户隔离靠项目(Project)而非用户组
Harbor 的租户边界实际由 Project 划分,不是用户或用户组。一个用户可以加入多个 Project,但每个 Project 内部的镜像、扫描策略、机器人账号完全独立。如果你误以为“给用户打标签”就能隔离资源,后续会发现镜像能跨项目拉取——因为没设对权限范围。
实操建议:
- 创建租户时,先建专属
Project(如acme-prod),再把对应成员加进去,角色选maintainer或developer - 禁用
Public项目,避免新用户默认获得全局读权限 - 用
robot account替代共享密码:每个Project单独生成,绑定最小作用域(比如只允许pull) - 别依赖 LDAP 组同步自动赋权——Harbor 同步的是用户身份,不是项目归属;必须手动把用户加进对应
Project
RBAC 权限粒度止于 Project 级,不支持 Repository 或 Tag 级控制
Harbor 的 RBAC 没有 repository:nginx:1.25 这种细粒度策略。你无法限制某人只能拉取 nginx:alpine 却禁止 nginx:latest。所有权限都挂在 Project 下,且只有五档固定角色:guest、developer、maintainer、project-admin、admin。
常见错误现象:
- 给用户设了
developer,结果他能删别人 push 的镜像——因为developer允许delete自己上传的 artifact,而 Harbor 不校验 uploader 身份 - 开了漏洞扫描,但
guest用户看不到扫描报告——因为报告查看权限需developer起步 - 用 API 批量授权时传错
role_id(比如把3当成maintainer,实际是2),导致权限静默失效
镜像推送失败报 403 forbidden?大概率是 Project 权限 + 机器人账号 scope 没对齐
这个错误不是认证失败,而是鉴权拒绝。典型场景:CI 流水线用机器人账号推镜像,但该账号只绑定了 pull 权限,或者所属 Project 被设为私有却没给机器人账号加成员。
排查步骤:
- 确认机器人账号的
token是否过期(有效期默认 90 天,不可刷新) - 检查该账号在目标
Project中的角色是否为developer或更高(guest不允许push) - 看
Project设置里的Public开关:关着就必须显式授权,开着则guest也能拉,但推仍需角色 - API 推送时注意
Content-Type必须是application/vnd.docker.distribution.manifest.v2+json,否则某些 Harbor 版本会拒收并返回模糊的403
升级 Harbor 后 RBAC 行为突变,重点查 system-robot-accounts 和 OIDC 配置
2.5+ 版本引入系统级机器人账号(system-robot-accounts),它默认拥有全项目 pull 权限,可能绕过你原有的项目隔离逻辑。同时,OIDC 认证开启后,用户角色不再继承自本地 DB,而是由 IDP 返回的 groups claim 决定——如果 IDP 没传 group,用户进来就是裸账号,没有任何 Project 权限。
关键差异点:
-
system-robot-accounts默认启用,且无法删除;如不需要,得在harbor.yml里关掉robot_token_expiration并重启 - OIDC 用户首次登录时,Harbor 不自动创建对应
Project成员关系;必须提前在 IDP 侧配置好 group 映射,或手动后台添加 - 旧版用
adminserver做权限缓存,新版改用 Redis;如果 Redis 连不上,RBAC 会退化为只读,所有写操作报403
最常被忽略的一点:Harbor 的 Project 权限不继承,也不叠加。用户在两个项目里分别是 developer 和 guest,他在各自项目里的能力互不影响——但很多人会下意识认为“高权限能跨项目生效”,其实不能。

















