隐私
索引了什么,脱敏了什么,什么永远不出这台机器
deja 索引的正是可能带着凭据的会话历史,所以隐私在这里是第一顺位的问题,不是事后补的。
索引了什么
对话本身,以及智能体在对话期间做过的事:工具调用提到的文件路径、执行过的命令、每次改动替换掉的那段原文,以及工具打印出来的内容。最后这一项正是脱敏重要的原因——命令输出里的凭据远多于散文——这些内容和对话本身走同一条脱敏流程。被替换掉的原文是你自己文件里的代码,存下来是为了让 deja restore 能把工作还给你,它和其他一切一样留在本机。
在 Claude Code 和 Codex 上,索引还会保留压缩前那一刻的一小包工作上下文——任务、结论、涉及的文件和命令,同样脱敏,最多 32 个会话/工作区组合。它放在索引清单里,不进 sync 导出,遵守被排除的项目和 DEJA_RECALL=off,而且即使那个会话还没被索引,deja forget 也能把它删掉。
默认只在本地
建索引和检索没有网络路径,索引及其使用日志不离开这台机器。只有四种情况会联网:deja update、deja sync ssh,doctor 里的版本检查(用 --offline 可以关掉),以及 deja embed——它会把文本发给你自己配置的嵌入服务,下面有详细说明。
脱敏
密钥在建索引时就被剥掉:API key、JWT、PEM/PGP 私钥块、bearer 与 HTTP Basic、各家提供商的令牌、scheme://user:pass@host 形式的 URL,(自 0.14.2 起)处在密钥位置上的裸高熵值——赋值右侧,或单独占一行的令牌——以及(自 0.20.2 起)写在散文里、名字和值之间没有任何分隔符的口令,比如「the admin password is …」。最后这条要求值里带数字或符号,所以「the password is wrong」这样的句子不会被动。
这一切发生在任何内容被写下之前。脱敏作用于完整消息、在长度截断之前,所以跨过截断边界的密钥也漏不过去。搜索、MCP 召回、share 和 sync 对外给出的都是脱敏之后的内容。
控制留下什么
- 排除项目——在
~/.config/deja/exclude写模式,或用DEJA_EXCLUDE_PROJECTS,建索引时就跳过;sync export同样遵守,所以后来被排除的项目不会离开这台机器。在规则存在之前已经索引过的会话,本地仍然可搜,直到deja index --rebuild——deja index会告诉你正处在这种情况。 - 排除整个工具——同一个文件里以
harness:开头的一行指的是某个智能体而不是项目,例如harness:opencode:deja 既不走这个存储,也不会去要读它所需的工具。逗号分隔的形式是DEJA_EXCLUDE_HARNESSES。名字是精确匹配而不是模式,就是deja sources打印出来的那些。 - 遗忘——
deja forget移除会话并写下墓碑,下次建索引不会把它们带回来;--dry-run预览,--list看墓碑,--unforget <id>撤销一条。 - 脱敏报告——
deja stats --redaction按规则和工具列出被遮盖了什么。 - 审计智能体收到过什么——
deja log列出最近的召回与注入,deja log --last原样打印最近一次送出的摘要。 - 信任范围——
~/.config/deja/policy.json决定哪种记忆在哪里生效。按激活路径(search、mcp、auto)允许或拒绝来源:local、imported(从另一台机器同步来的),或者某一台具体的机器,例如imported:mini。举个例子——同步来的会话可搜,但永不自动注入:{"activations":{"auto":{"imported":false}}}。deja embed是唯一会把会话文本发出机器的命令,所以它要求三条路径一致同意:任何一条规则不放行的内容都不会被嵌入。
模式匹配不是密钥检测:某家新提供商的令牌形状、没有名字的凭据、编码或变形过的数据、跨行断开的密钥,都可能原样通过;脱敏也无法去掉「看起来不像凭据的敏感文字」。分享或导出之前请自己看一眼。完整边界写在安全模型里。
还有一句值得直说:出现在记录里的凭据,早就被写下它的那个智能体发给模型提供商了。脱敏保护的是从那份记录派生出来的东西——本地索引、分享、同步——它不能撤销原来的暴露。请轮换那个凭据。