案例更新 2026-10-29

Onyx:撤权以后,知识问答何时真正停止提供资料

本页目录 · 5 个段落

企业知识问答不能只证明员工能找到资料,还要证明权限变化后,不该看到的人何时不再看到。Onyx 的公开实现把问题落到两种状态:用户属于哪些组,文档允许哪些主体。它们分别同步,再在搜索时按当前用户标识与文档允许范围匹配。一次源系统撤权,需要沿两条传播链核对;数据库显示已改或任务显示成功,都不是终点。

本文按固定源码解释标准搜索路径,外部群组与源权限同步涉及 Enterprise Edition(EE,企业版),不能当成社区版安装后自动具备的能力。项目|企业版许可

撤权需要穿过身份、文档与索引
  1. 01

    源系统改变可见性或成员

  2. 02

    更新用户及文档访问关系

  3. 03

    后台同步索引访问字段

  4. 04

    查询前按当前身份过滤

  5. 05

    验收:记录撤权后的查询结果

依据固定源码整理传播关系;最后一步为本文建议的部署验收,不声称已运行完整撤权实验。

抓取凭据能看到,不等于提问人能看到

连接器持有来源读取凭据,可能抓到比单个员工更多的资料,索引因此还要保存文档访问范围。DocumentAccess 将邮箱、内部组、外部组等编码成访问标识;外部组带来源前缀,避免不同来源同名组相互混用。查询端根据登录用户构造 ACL,即访问控制列表,不使用聊天里自行声称的身份。访问模型|访问构造

企业版从本地数据库取得内部与外部组关系,加入本次查询 ACL,并非每次问答都实时向 GitHub、Drive 等来源询问成员身份。企业版用户 ACL

搜索范围与权限不同:助手绑定的文件、目录或文档集合决定从哪片知识找,ACL 决定其中哪些允许给当前用户。相关知识范围可以有并集,外层仍与权限、时间、租户及隐藏状态等条件相交;指定一个知识集不应解除 ACL。搜索装配

OpenSearch 将可见性表示为公开文档或 ACL 至少命中一项。关键空值语义是 access_control_list=None 表示不加权限限制,空列表则仍限制为公开资料。两者不是等价的没有权限值;排查绕过路径必须看上游何时允许传 None。查询过滤

成员与文档撤权,有两只时钟

用户关系与文档权限分别传播可横向查看,点击打开原尺寸 ↗

固定版本 06aa2b0:成员关系影响查询侧 ACL,文档访问范围另经异步任务投影到索引;两者没有公开的统一即时生效保证。

从组里移除用户,可以更新本地成员关系,使下次查询不再携带该组标识,不必重写所有文档;文档从某组移除或公开转私有,则需更新文档权限并传播索引。两者来源请求、调度、失败窗口不同,不能用权限每几分钟刷新概括。

外部组同步先将旧关系标记 stale,再按来源枚举结果分批 upsert,使仍存在的关系恢复为非 stale,成功后删除剩余旧关系;下轮开始还会清理上轮遗留。标记阶段提交数据库事务,避免跨耗时外部 API 请求持有事务。群组存取|同步循环

但 stale 标记不是即时拒绝:fetch_external_groups_for_user 只按 user_id 取关系,没有过滤 stale。只有清理实际发生,旧关系才不再进入用户 ACL。这解释了中断窗口:开始同步、已打 stale,不能当撤权已兑现;也不能由此直接断言线上泄露。实际窗口需要目标连接器、配置和部署实测。

文档侧则由源权限进入 PostgreSQL,修改水位使其成为待同步对象,再由任务把 ACL 等元数据送到实际索引。抓取周期只是起点,积压、来源错误和索引重试均可能延后生效。同步调度

同步任务为何拆成三个阶段

读库、索引I/O与水位回写可横向查看,点击打开原尺寸 ↗

固定版本 06aa2b0:索引 I/O 不持有 PostgreSQL 事务;确认水位沿用最初读到的 last_modified,保护并发变更。

document_index_metadata_sync_task 先在事务中读取文档、访问范围与 last_modified,关闭连接;在事务外向索引更新;最后新开事务写同步完成水位。元数据任务

网络重试因此不长时间占数据库连接;完成水位使用最初读到的 last_modified,而非结束时间。同步期间若又改权限,新修改仍应待同步,不会被刚完成覆盖。若索引成功、回写数据库前崩溃,下轮可能重复同步;代码选择允许重做而不是提前声称完成。

重建索引时可能同时写主、次索引。仍在填充的索引尚无该文档时,任务保留待补状态,避免全量复制之后把旧权限重新装回。路径名虽含 vespa,此任务通过工厂处理实际索引实现,不能看目录名认定所有部署相同后端。

上游测试检查索引 I/O 期间不持有 PostgreSQL 事务。这证明特定资源边界,不证明生产撤权时延。回归测试

公开转私有,还要看索引字段

OpenSearch 初次写入把 public 单独存为布尔字段,从 ACL 数组移除公开标识;查询又把 public=true 与命中 ACL 作或。因此只改 ACL 数组,不一定能撤掉文档公开状态。索引表示

固定版本增量 update 路径可观察到:载荷包含 ACL,未单独写 public。既有研究用原函数和收集请求的惰性客户端,分别输入公开和非公开状态,确认该载荷缺项。它未启动真实索引、未覆盖全量重索引,也未证明真实权限事件只走该路径。这是需集成验证的接缝,不是已证实产品漏洞。增量实现

有用的核验是对获准测试资料只改变公开性、不改正文,检查完成同步后的实际 public、ACL,再让无权用户新会话查询。数据库私有、索引仍公开或搜索仍返回,是不同层问题;局部探针通过不能替代端到端权限验收。

暂停、删除与旧会话另行验收

暂停抓取不等于清除既有索引;删除传播可能依靠按连接实例计算的 pruning,即比较本地与来源文档标识、清理差集。同一内容若由多个实例引入,一处来源移除不证明所有副本与历史答案立即消失。清理实现

队列代码中的 revoke 还可能指撤销 Celery 后台任务,目的是清理任务跟踪和阻塞标记,不是用户权限撤销;Redis 七天防御性 TTL 也不是撤权承诺。相同词汇不能合并成一个业务保证。

采用时,用现有测试账号与获准资料,分别验用户退出组和文档公开转私有。记录来源变更、本地关系、文档水位、索引字段、新会话负向查询的时间,按安全要求设传播上限;再中断一次同步看能否恢复。旧会话、分享链接和已生成答案的保留政策单独验收。终点是系统真正停止提供资料,而非某个权限任务运行过。

案例资料与日期

公开企业研究 · Onyx · 企业知识问答与撤权传播

行业
企业软件
场景
知识检索
应用阶段
开源产品
上线时间
未披露
来源发布日期
未披露
站点更新
2026-10-29

来源发布日期与上线时间分别记录;未披露不表示尚未上线。

公开来源

封面:依据Onyx固定版本源码与公开连接器说明整理;原创知识权限机制图,非官方截图。;同步与撤权有传播窗口。

把这一页用到你的工作里

来源与使用范围

基于公开来源的案例研究;能力、效果与规模以来源披露范围为准,参考设计单独标明。

一起判断下一步

带一笔任务,聊一个具体决定。

培训、方案评审或落地辅导,从你的工作材料与当前困难开始。

交流我的场景