Files
xinmi/docs/wiki/安全认证/RBAC说明.md
T
yawan f7fc992f57
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
2026-09-22 16:19:06 +08:00

5.0 KiB
Raw Blame History

title, tags, aliases, source
title tags aliases source
空间RBAC说明
安全认证
RBAC
权限
多空间
角色
RBAC
角色权限
空间角色
TenantRBAC
RBAC说明.md

空间 RBAC 说明

本文档介绍 WeKnora 的空间内权限控制(Workspace RBAC),包括角色矩阵、资源归属模型,以及它与 共享空间 的关系。

状态:已发布;由配置项 tenant.enable_rbac 控制,默认 true(强制鉴权)。 完整说明、灰度方案、Schema、路由守卫等参见 docs/RBAC说明.md。

解决的问题

RBAC 引入前,只要通过 X-API-Key 或 JWT 认证成功,调用方在空间内基本等同管理员。一旦一个空间出现多名真人成员,就需要区分:

  • 谁可以删除知识库、撤销 API Key;
  • 谁可以编辑「自己」的 KB / Agent;
  • 谁只读。

角色矩阵

角色 标识 关键能力
只读 viewer 仅读
贡献者 contributor 可变更 creator_id == 自己 的资源;他人资源按 Viewer
管理员 admin 可变更空间内任意资源;管理成员、共享基础设施
Owner owner Admin + 可删空间;每个空间至少一位,可以有多位

层级 viewer < contributor < admin < owner,高角色继承低角色。

Owner 的数量约束是“至少一位”,而不是“只能一位”。系统允许同一空间存在多个活跃 Owner;降级或移除 Owner 时,只有会导致空间失去最后一位 Owner 的操作才会被拒绝。

鉴权层的例外

  • 跨空间超管:enable_cross_tenant_access 打开且账号 CanAccessAllTenants=true,通过 X-Tenant-ID 切换后等同 Admin。
  • API Key:合成虚拟用户在所属空间内固定 Admin(删空间除外)。
  • 孤儿空间自愈:首位认证的真人自动晋升 Owner,避免 API Key-only 空间锁死。

资源归属

迁移 000043 在关键表加上 creator_id:

  • knowledge_bases.creator_id —— 老数据回填为该空间的 Owner;
  • custom_agents.creator_id + runnable_by_viewer(默认 true,允许 Viewer 在对话中调用)。

子资源沿 chunk → knowledge → kb → creator_id 链回溯。

由此得到两类守卫:

  • 角色守卫:只看角色,用于空间级基础设施(模型、向量库、IM 通道等)。
  • 归属守卫OwnedXxxOrAdmin:creator 或 Admin+ 二者其一即放行,用于具体资源写操作。

与共享空间的关系

维度 解决什么 主键
空间 RBAC 同一空间内「你能对自己/别人/共享基础设施做什么」 tenant_members(user_id, tenant_id, role)
共享空间 跨空间「让别的空间的人也能用我的 KB / Agent」 organization_members + 共享关系

两者正交:

  • 共享空间不持有 KB / Agent,只记录「以何种权限共享到了哪个空间」;资源归属与 creator_id 不变;
  • 一次对他人共享过来的 KB 的写操作,需要同时满足:共享时设了「可写」 + 你在该空间不是 Viewer + 源空间的 RBAC 仍然放行;
  • API Key 跨空间访问不会带 Admin 光环——共享路径由 organization_members.role 决定,与 API Key 无关。

判定顺序见 internal/middleware/kb_access.go:

KB 属于我当前空间?─是─► 走空间 RBAC(角色 + creator_id)
            └─否─► KB 共享给我所在空间?─是─► 取 min(共享权限, 空间角色)
                                       └─否─► 403 / 404

一句话:空间 RBAC 是纵向的纵深防御,共享空间是横向的协作通道;跨空间写动作必须同时穿过两道闸口。

配置

tenant:
  enable_rbac: true          # false 则进入「仅记录不拦截」灰度窗口
  enable_cross_tenant_access: false
auth:
  registration_mode: self_serve   # 或 invite_only
audit:
  retention_days: 90              # 0 表示不清理

环境变量 WEKNORA_TENANT_ENABLE_RBAC / WEKNORA_AUDIT_RETENTION_DAYS 覆盖 YAML。DISABLE_REGISTRATION=true 等价于把 registration_mode 强制设为 invite_only。

审计

audit_logs 表记录:

  • rbac.member_added / removed / role_changed / left
  • rbac.access_denied(仅强制鉴权时;1 分钟滑动窗口去重)

每日后台 goroutine 清理超过 audit.retention_days 的旧行。

相关主题


反向链接