WeKnora 文档权限控制完整指南:如何用 5 分钟配好 RBAC 角色与多租户数据隔离
【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora
打开同一个知识库,你能浏览、同事能编辑、而陌生人只会被 403 挡在门外——这就是 WeKnora 文档权限控制的日常。本指南从真实协作痛点出发,带你用 6 个步骤走通 RBAC(基于角色的访问控制)与多租户数据隔离的完整链路,让你 5 分钟内给自己空间配好权限。
同一份文档,不同的权利:为什么需要权限控制
想象这个场景:你搭了一个团队共享的 WeKnora 知识库,把产品文档、合同、周报都丢了进去。三个月后,实习生误删了核心知识库,外部合作方却能看到不该看的合同。问题不在"进没进门",而在"进门之后能走到哪一层"。
WeKnora 把这套权限体系设计成类似小区管理的三层结构:
- 门禁卡(认证):确认"你是谁"。没有卡,连小区大门都进不去;
- 工牌(授权):确认"你能干什么"。访客、住户、物业、业主,工牌颜色不一样,能开的门就不一样;
- 楼层分区(数据隔离):确认"你在哪栋楼"。A 栋住户永远摸不到 B 栋的门把手。
接下来我们用一张表把这三件事钉死。
一张对照表快速看懂认证、授权、数据隔离的分工
| 层次 | 生活类比 | 回答的问题 | WeKnora 的实现方式 | 出错时你看到什么 |
|---|---|---|---|---|
| 认证 | 门禁卡 | 你是谁? | JWT Bearer 令牌(网页登录)或 X-API-Key(脚本集成) | 401 Unauthorized |
| 授权(RBAC) | 工牌 | 你能干什么? | viewer / contributor / admin / owner 四级角色 + 资源归属(creator_id) | 403 Forbidden |
| 数据隔离 | 楼层分区 | 你在哪栋楼? | 空间(tenant)ID 注入请求上下文,所有查询按 tenant_id 过滤 | 404 或 TENANT_REQUIRED |
关键认知:三层是串行关卡,不是三选一。一个请求必须先刷门禁、再查工牌,最后才允许进楼层。任何一层不通过,请求都会被拦下,且每一层的拦截行为你都能通过状态码区分(401 是没登录,403 是权限不够)。
跟着一个请求走完全程
我们拿"用户小赵打开知识库列表页"当例子,把整个链路走一遍。
第 1 步:登录换门禁卡。小赵在登录页提交邮箱密码后,服务端发回一对令牌:短期有效的 access_token 和长期有效的 refresh_token。access_token 就是他的门禁卡,过期前可以反复刷。
第 2 步:请求带上卡片。之后每次请求,前端都在请求头里带上这张卡。认证中间件会按固定顺序处理:先查白名单(登录、健康检查这类公开接口直接放行),再验证 JWT:
// internal/middleware/auth.go 核心流程(简化) if token, ok := bearerToken(c); ok { user, err := userService.ValidateToken(ctx, token) if err == nil { applyAuthSession(c, session) // 用户+空间+角色写入上下文 c.Next() } } // JWT 无效时再尝试 X-API-Key,最后都失败才返回 401第 3 步:确认楼层。JWT 验证只是认出"小赵",还要确定这次操作属于哪个空间。判定优先级是:X-Tenant-ID请求头 > JWT 里的空间声明 > 小赵的第一个有效成员身份。这也是前端空间切换器能工作的前提——
第 4 步:查工牌。中间件在小赵要访问的空间里查成员表(tenant_members),解析出他的角色,连同用户、空间一起挂进请求上下文。如果小赵在这个空间压根没有成员记录,强制鉴权模式下直接 403。
第 5 步:数据层的自动过滤。到了业务层和数据库层,空间 ID 已经躺在上下文里,所有查询都会自动带上tenant_id = ?条件——这就是多租户数据隔离落到代码里的样子:不是每个开发手动记着加条件,而是上下文一路带下来,层层自动过滤。
第 6 步:留痕。如果小赵角色不足被拒,这次拒绝会写进 audit_logs 审计表(带 1 分钟去重防刷表),事后可追溯。整个链路下来,认证、授权、隔离三层各司其职,谁也没越权。
一张表看懂角色:从只读到 Owner 的权限边界
WeKnora 的空间角色是一个刻意保持精简的四级矩阵,高角色自动继承低角色的全部权限:
| 角色 | 身份比喻 | 能读什么 | 能改什么 | 典型使用场景 |
|---|---|---|---|---|
| viewer 只读 | 访客 | 空间内全部内容 | 什么都不能改 | 只查阅、只提问的成员 |
| contributor 贡献者 | 住户 | 空间内全部内容 | 自己创建的知识库、Agent 及其子资源 | 上传文档、维护自己那一摊 |
| admin 管理员 | 物业 | 空间内全部内容 | 空间内任意资源 + 管理成员 | 空间运维、配置模型/存储/向量库 |
| owner 所有者 | 业主 | 全部 | admin 全部 + 可删除空间 | 空间创建者,每个空间至少一位 |
这张表里最精巧的是 contributor 一行的加粗部分——归属模型。除了角色这一道闸,WeKnora 还给每个知识库记了一个 creator_id 创建者。判定写权限的规则是"我是这条资源的创建者,或者我至少是 admin",满足其一即可。于是"Contributor 在自己的 KB 里像 Owner,在别人的 KB 里像 Viewer"就自然成立了,子资源(文档块、FAQ、标签)则顺着归属链回溯到知识库的创建者。
两个特殊身份值得你记住:
- API Key 调用:X-API-Key 认证的虚拟用户在所属空间内固定按 Admin 对待,脚本集成不需要为角色操心;
- 跨空间超管:开启跨空间访问后,特定用户可用
X-Tenant-ID切到任意空间,按 Admin 权限操作。
把权限调到既安全又顺手
配置都在 config/config.yaml 里,核心就三个开关:
tenant: enable_rbac: true # 强制鉴权;false 进入"只记录不拦截"灰度 auth: registration_mode: invite_only # 关闭公开注册,只走邀请链接 audit: retention_days: 90 # 审计日志保留天数给你四条可落地的建议:
- 灰度上线别硬切。担心升级后权限收紧伤到现有脚本?先把
enable_rbac设为 false 跑几天,观察日志里"已记录但未强制"的拒绝项,逐条修正成员角色后再切回 true。回滚只需改回 false 重启。 - 企业部署关掉公开注册。默认 self_serve 允许任何人注册并自建空间,适合个人学习;团队环境改成 invite_only 后,登录页注册入口会自动消失,所有新成员必须通过管理员发出的邀请进入。
- 人机分权。人用 JWT 登录走角色体系,脚本用 API Key 走 Admin 通道。这样脚本挂了、Key 泄露的影响面,和真人误操作的排查路径是两条线,好查得多。
- 审计日志是排障利器。每次成员增删、角色变更、越权拒绝都有记录,保留 90 天起步;安全事件倒查时,它就是你最好的时间线。
另外两个底层保障不用你操心但值得知道:密码以强哈希存储且 API 响应里永远不序列化;令牌支持 Logout 撤销,refresh_token 过期需重新登录。
新手最常踩的 4 个坑
坑一:升级后空间里找不到 Admin,人人都是 Contributor?回填逻辑会把"最早活跃的用户"选为 Owner,其余统一成 Contributor。如果那个最早的用户是机器人或共用账号,把机器人降级、真人提升即可,每次调整都会进审计日志。
坑二:切到强制鉴权后,某个脚本突然 403?大概率是脚本对应的人类成员角色不够。两条出路:把该用户提升为 Admin,或者脚本改用 X-API-Key 调用(Key 在所属空间固定 Admin)。
坑三:共享空间会不会绕过空间 RBAC?不会。共享空间是"横向"的协作通道,空间 RBAC 是"纵向"的纵深防御,任何跨空间的写操作要同时穿过两道闸口。哪怕 KB 被以"可写"共享过来,若源空间里它属于"仅 Admin 可写",外空间成员也只能读。
坑四:审计表里怎么有的 403 找不到记录?两种可能:同一来源的拒绝在 1 分钟滑动窗口内只写一行(防恶意探测刷表);或者你还处在 enable_rbac=false 的灰度模式,此时不写拒绝记录。完整的逐条序列在应用日志里永远可见。
现在轮到你了
权限体系的最终目的不是锁死一切,而是让"谁能看、谁能改"变成一件确定且可预期的事——门禁管住入口,工牌划清边界,楼层分区守住数据,审计日志兜住底。
下一步很具体:打开成员管理页,给你的第一位同事分配合适的角色,然后观察一次 403 是如何被记录下来的。配置细节可对照 docs/RBAC说明.md 与 docs/共享空间说明.md,权限链路的源码在 internal/middleware/auth.go 和 internal/handler/auth.go。
【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考