多租户记忆库将隔离落实到SQL
ragleap-memory与ragleap-security发布首版,介绍了SQL内作用域过滤、删除字节验证及哈希链审计日志。作者还报告了单元测试和变异测试结果,并指出不同错误响应可能泄露记录是否存在。
AI 深度解读
给 AI 加一份长期记忆,难点不只是「能搜到」,还包括租户之间是否会泄露记录存在、删除后文件里是否还留着内容。作者发布的 ragleap-memory 0.1.0 和 ragleap-security 0.1.0,尝试用一个 SQLite 文件处理这两件事。
它的看点是把隔离约束放进 SQL,并检查硬删除后的残留字节。不过,测试覆盖了哪些情况,决定了这些承诺能成立到哪里。
隔离不只是不返回内容,还要隐藏记录是否存在
作者指出一种容易被忽略的泄露:访问不存在的记录返回「未找到」,访问其他租户的记录却返回「无权限」。即使正文没有泄露,调用方也能判断某条记录存在。
ragleap-memory 的做法是让 SQL 查询直接包含 scope 过滤,并让不存在与超出范围得到相同响应。边界判断由数据库查询落实,减少上层调用遗漏检查的机会。
配套的 ragleap-security 提供 Scope.parse()、covers() 和 narrow(),用于表达和收窄组织、区域、分支等范围。它只有 5 个模块,仅依赖 Python 标准库。另有 SecretStr 隐藏打印表示中的秘密值,check_size(data, max_bytes=1_000_000) 限制数据大小。
审计使用带哈希链的 JSONL:修改中间一行,会破坏后续校验关系,AuditLog.verify() 因而失败。这是篡改可检测,不是阻止篡改;它也不能代替文件访问控制。
「忘记」和「擦除」是两种不同承诺
这段代码展示了记录更新与删除的区别:
id1 = store.add(text="Old threshold", type="fact", scope=scope_a) id2 = store.supersede(id1, text="New threshold is 80", scope=scope_a) # history kept
store.forget(id2, scope=scope_a) # soft delete store.erase(id2, scope=scope_a) # hard delete + vacuum
要注意最后一行:原文把 erase() 放在了注释之后,直接复制不会执行硬删除。这里保留原样,是为了说明作者区分的操作语义。
supersede() 保留历史,forget() 做软删除,erase() 则执行硬删除并配合 vacuum 整理数据库。查不到记录,与文件里找不到原文,是两种不同的验证。
作者称,他们在两个 SQLite 构建上做了擦除后的字节搜索。这比只检查查询结果更进一步,但原文没有展开具体测试步骤,也没有证明备份、文件系统快照等其他副本一起消失。
记忆条目分为 episode、fact、summary,分别保存原始事件、提炼事实和压缩摘要,默认都是 untrusted,需要显式标记信任。其他操作包括迁移导出 export、清理 TTL 过期记录的 sweep_expired、执行 vacuum 的 compact,以及不记录条目正文的可选审计日志。
检索采用 FTS5 全文搜索,不使用向量。作者看重确定性、离线可用和没有 embedding 成本。印地语、泰米尔语、阿拉伯语及带空格中文做过整词测试;不带空格的中文、日文尚未分词。对国内读者,这个限制直接影响可用性。
测试数量之外,作者还验证了什么
ragleap-security 有 101 项测试,ragleap-memory 有 89 项。作者还运行 scripts/mutation_check.py,故意把 == 改成 !=、删除 WHERE 条件,再看测试是否失败。这叫变异测试:检查测试能否抓住被人为植入的错误。
正文明确报告 security 的 30/30 个变异被捕获;标题另提到 27 个变异,但正文没有展开对应结果,不能自行补齐。
发布流程也做了校验:打标签前本地构建,打标签后由 CI 构建,比较 SHA-256,不一致就失败。作者称两个版本的本地摘要均与 PyPI 一致。它证明构建产物一致,不证明程序没有安全缺陷。
我的判断
我赞成把 scope 条件落实到 SQL,并统一越界与不存在的响应。这比要求每个业务调用点自行记得鉴权,更容易形成稳定约束。不过,参数化的 WHERE tenant_id = X 同样是在 SQL 中过滤;原文没有给出常见方案的对照实现,不能据此认定其他记忆库普遍存在漏洞。
FTS5 也有合理取舍。关键词明确、要求离线的场景可以受益;需要语义召回时,向量检索仍有价值。作者没有提供 precision/recall 基准,因此检索效果目前不能比较。
作者明确承认:未测试 Windows、NFS、多进程写入和断电恢复,没有独立安全审查,隔离能力也尚未接入其他系统。两个库都是首次发布的 v0.1.0。现阶段更适合把它当作可审查、可试验的基础组件,端到端安全仍需集成验证。
能拿来做什么
- 检查现有 AI 记忆接口,让「记录不存在」和「记录不属于当前租户」使用一致响应,并补上跨租户访问测试。
- 如果产品承诺彻底删除,分别验证查询结果和数据库文件残留;备份中的副本需要另行处理。
- 用真实中文资料试跑 FTS5,尤其检查无空格输入,再决定它能否满足检索需求。
- 在隔离测试中尝试移除 scope 条件,确认测试会失败;评估这两个 Python 库时,可使用
pip install ragleap-security==0.1.0和pip install ragleap-memory==0.1.0安装对应版本。