Memories / 文档

本页目录

无人值守桌面 CLI 与 MCP

无人值守访问是一项需要显式启用、仅限本地、只读的能力,适用于选定的活动保险库。它包含普通及私有记忆/卡片、原始二进制文件、修订历史,以及显式请求的凭据明文。只有在你信任接收客户端能够接触这些保险库中的每项资产和秘密时,才应启用它。它不是普通 MCP 权限,也不是永久 sudo 会话。

登记并选择托管方式

在独立终端中启动守护进程,每条命令都使用同一个专用绝对 home 路径。先按常规流程初始化资料库并创建保险库。以下路径仅为示例;请在各平台使用自己的私有目录。

memories --home /absolute/private/home daemon

在交互式终端中显式选择后端:

memories --home /absolute/private/home unattended enable --backend linux-secret-service

登记时会警告客户端能够读取已存储的密码,要求输入 ENABLE,随后提示输入本地密码以解锁,再输入一次以获取 sudo 权限。这套同意/密码设置仅在登记时需要一次,无需在每次无人值守读取时执行。不要通过参数或环境变量传递密码。后续管理仍需要一个通过普通密码解锁并获得 sudo 授权的终端。

后端 托管方式与要求
windows-dpapi 当前用户的 Windows DPAPI;受保护文件使用仅所有者可访问的权限。没有机器级范围,也没有认证界面。
macos-keychain 不同步的 macOS Keychain 条目;访问需要解锁或批准时会拒绝,而不会弹出提示。
linux-secret-service 会话总线上的 Secret Service,要求集合/条目已解锁。不会请求 Unlock 或调用 Prompt。
owner-file 桌面端需显式选择的较低保护方案:封装材料以明文存放在仅所有者可访问的文件中,不提供抵御该操作系统账户的加密保护。

例如,主动选择较低保护方案可使用 unattended enable --backend owner-file。原生后端不可用或需要交互时,不会自动回退。Secret Service 依赖本地操作系统账户/D-Bus 边界;客户端无法控制任意提供者特有的界面行为。后端只能在创建时选择。不要编辑其元数据来切换后端。托管绑定规范化的存储路径和当前头部标识,因此将它复制到其他存储并不等于登记。

密码封装仍可用于常规解锁和恢复。登记会增加一个独立的主密钥封装,其封装密钥保留在数据库之外;它不会取代密码认证。

生成客户端文件

在同一个已授权终端中,为客户端所需的保险库生成授权:

memories --home /absolute/private/home unattended mint --vault VAULT_ID --client-file /absolute/private/home/client.json
# Repeat --vault VAULT_ID to include another vault in this grant.

父目录必须已存在,且仅所有者可访问。生成过程以原子方式发布文件,不会覆盖现有文件,并拒绝不安全的所有权、权限或链接。发布失败时会尝试撤销新授权,并报告撤销失败。输出包含授权 ID 和文件路径,绝不包含 bearer 令牌。保留该 ID,以便撤销。

此客户端文件独立于普通 MCP 授权文件。应像保护密码一样保护它;不要打印其内容、提交到版本库,或将令牌放入命令参数。CLI/MCP 读取需要显式通过 --client-file 选择,并使用相同的 home/存储。范围是选定保险库的 read_only_all_assets,并非逐资产授权或仅普通内容授权。每次读取都会重新检查当前本地设备成员资格和保险库范围。

启动与读取

登记后重启守护进程,以使用仅加载密钥的启动方式。停止时不要执行 memories lock,然后使用同一个 home 再次启动。启动成功后会加载无人值守密钥,但普通状态仍报告 unlocked: false:普通读取、写入、sudo、云端工作和 RAG 会保持锁定,直到使用密码解锁。后端失败时无人值守密钥不会加载,也不会回退到密码或环境中已有的认证。

在 Unix 上,强制终止可能在 home 目录留下 service.sock。只有确认其守护进程已停止后,才能删除该过期套接字。

memories --home /absolute/private/home unattended list VAULT_ID --client-file /absolute/private/home/client.json
memories --home /absolute/private/home unattended history VAULT_ID ASSET_ID --client-file /absolute/private/home/client.json
memories --home /absolute/private/home unattended read VAULT_ID ASSET_ID --client-file /absolute/private/home/client.json
memories --home /absolute/private/home unattended credential-bytes VAULT_ID CREDENTIAL_ID --client-file /absolute/private/home/client.json

列表返回资产元数据,包括私有资产、文件和凭据资产,但不返回正文;墓碑记录会被省略。历史返回修订元数据,包括 head/deleted/quarantine 标志,不包含凭据正文。当前资产存在冲突时,必须显式指定匹配的修订。可以显式读取历史修订和已删除修订,但会拒绝隔离修订。此路径读取活动保险库历史,而非恢复归档。

read 返回记忆/卡片的 Content JSON 字节或文件的原始字节,拒绝凭据。credential-bytes 仅接受凭据,返回已存储正文的 UTF-8 字节;显式选择时也包括历史值。它不会新增任意二进制凭据存储支持。受保护卡片和 wiki 的秘密引用仍保留为引用;如有需要,应单独请求其引用的凭据。

重组完整字节

响应的 data 包含不带填充的 base64url,并提供从零开始的 offset、字节数 total、next(完成时为 null)、实际 revision 和 encoding(content_json 或 raw_bytes)。获取完整内容时:

  1. 从偏移量 0 开始请求,--limit 为 1 至 65536 字节(默认 65536)。
  2. 将每个响应的 data 分别按不带填充的 base64url 解码。
  3. 使用 next 作为下一个 --offset,并在每个后续请求中通过 --revision REVISION_ID 固定首次返回的修订。
  4. 持续请求直到 next 为 null,再按顺序拼接解码后的字节范围。只有此时才能按需解码 UTF-8/JSON;一个范围可能截断 UTF-8 字符。

例如,后续范围请求使用:

memories --home /absolute/private/home unattended read VAULT_ID ASSET_ID --client-file /absolute/private/home/client.json --revision REVISION_ID --offset NEXT_OFFSET --limit 65536

credential-bytes 使用相同选项。不要拼接编码后的字符串,也不要将首个范围当作整个资产。列表/历史使用 --offset 和 --limit,每页 1 至 100 项(默认 100);分页反映当前状态而非快照,因此请求之间的变更可能影响排序和总数。

通过 MCP 连接 AI 客户端

配置独立的 stdio 服务器命令,使用相同的 home 和客户端文件:

memories --home /absolute/private/home mcp serve-unattended --client-file /absolute/private/home/client.json

它仅公布 unattended_list、unattended_history、unattended_read 和 unattended_credential_bytes。工具参数为 vault、asset(列表除外)、可选的 revision(字节读取)、offset 和 limit。工具结果在 MCP 文本内容中包含相同的分页/范围 JSON;完整下载遵循前述字节范围契约。没有资产变更、执行、管理、同步、备份转储、搜索/模型执行或 OTP 计数器推进工具。读取会在返回输出前保存已签名的交付意图;审计/存储失败时拒绝输出。

普通 mcp serve --grant-file 保持不变,仍排除私有内容、文件和凭据读取。两种服务器都不会继承终端 sudo。由 Center 管理的存储拒绝无人值守登记/启动/使用。HTTP/WebSocket、中继 RPC、移动端 FFI/共享和 WebUI 无法使用无人值守权限。这些命令会拒绝远程参数、环境连接选项以及已保存的远程默认值,即使可执行程序帮助中出现了全局远程选项。

凭据 base64 是编码,不是加密。 无人值守 MCP 有意向接收客户端提供秘密字节。AI 提供商、会话记录、工具日志、缓存或插件可能保留或传输编码值或解码后的明文。只读范围可防止通过该能力进行变更,但无法防止披露或在其他地方使用已复制的秘密。测试时应使用合成秘密。

锁定、恢复、撤销与禁用

memories --home /absolute/private/home lock

手动锁定会清除密钥,并持久化禁止无人值守启动的状态,重启后仍有效。仅通过密码解锁不会恢复无人值守访问。如果持久化写入失败,锁定会返回错误;不要假定禁止状态已在不可写设备上持久化。空闲/关闭清理不属于手动禁止。

管理需要在本地终端中使用密码解锁并获取 sudo 权限:

memories --home /absolute/private/home unlock
memories --home /absolute/private/home sudo
memories --home /absolute/private/home unattended status
memories --home /absolute/private/home unattended resume

状态会报告启用/禁止状态和授权 ID,不报告令牌。恢复后,应在不手动锁定的情况下重启守护进程,返回仅加载密钥的状态。移除一个客户端或禁用所有无人值守访问:

memories --home /absolute/private/home unattended revoke GRANT_ID
memories --home /absolute/private/home unattended disable

撤销是持久化且幂等的操作。禁用会先持久化禁用权限并撤销所有授权,再清理后端。若有人复制了客户端文件,仅删除文件并不等于撤销。锁定、撤销和禁用无法收回已经交付的明文;应通过相应提供商轮换已暴露的凭据。

恢复与验证限制

无人值守封装/权限记录不包含在逻辑导出备份、设备配对或保险库同步中。恢复逻辑备份不会恢复无人值守登记。完整的原始本地数据库副本仍包含辅助表,文件系统备份也可能复制客户端文件或托管材料。同账户进程、操作系统管理员、进程内存、整机回滚和安全擦除仍不在 SECURITY.md 的保障范围内。

已实现的适配器覆盖 Windows DPAPI、macOS Keychain、Linux Secret Service 和 owner-file 托管。Linux 端到端验证使用 owner-file 托管、真实守护进程、私有记忆、原始二进制文件以及合成 UTF-8 凭据。验证覆盖仅加载密钥的重启、CLI/标准输入输出 MCP、普通/云端/RAG 拒绝、重启后仍有效的手动禁止、恢复、撤销和禁用。Linux 托管测试和隔离的 D-Bus 协议夹具提供额外覆盖,但该夹具不是实际桌面密钥环测试。

Windows/macOS 原生往返测试、原生锁定/需要批准及无界面行为,以及实际桌面密钥环验证仍是发布门槛。跨目标构建或错误转换测试无法证明这些原生行为。独立审查尚未完成;测试通过不等于安全审计。针对性的验证命令见 CLI 实现说明 和核心契约。