本地 CLI / TUI 管理端、自动化的可信凭据输入器、broker、MDBX3 引擎、系统 TLS 信任根和配置目录属于可信侧。AI 可提交 CLI 的公开管理参数,由可信输入器把必要凭据直接送入该进程;AI 通过 MCP 提交授权服务操作的结构化参数;明确的 api-read/api-write 授权允许完整服务 API,仍不能请求其他来源或替换认证头。仓库内容、WebDAV 目录列表及下载文件属于外部数据。
MCP bridge 不打开保险库,不读取主密码或服务 Token。它持有 256 位随机网关 capability,只能使用明确授予的连接、仓库、操作和有效期。broker 配置只保存 capability 的 SHA-256 摘要,并在每次请求和发送前重新校验授权。创建授权需要通过隐藏输入或可信管道提供保险库密码,MCP capability 不能代替管理凭据。
AI 侧授权不会永久有效:每份授权都带到期时间,并可再设总调用次数上限,已用次数落盘保存,broker 五分钟锁定重启不会把它清零。窗口或次数耗尽后代理只返回 reauthorization_required,AI 无法自行延长或换发;只有输入保险库密码的人执行 monica refresh 才能续期,续期换发新 capability,旧 bearer 当场失效,MCP 客户端需重启才能继续。
授权还可以要求"先问本人一句":approval 档位为 write 时每次写入、为 all 时每次调用,在请求离开本机之前进入内存审批队列,由持有解锁保险库的那个进程向人提问(TUI 模态框或 serve 终端的 [y/n])。队列不落盘、不网络监听,MCP bridge 只看到等待结果;不存在 monica approve 或第二条应答通道,因为那等于让 AI 自己批自己。人不在终端前时该调用最多等 15 秒后返回 approval_timeout,请求没有发出;档位、超时和队列上限都在代理侧判定,AI 只能从 catalog 的 authorization.approval 读到"这里有门槛",不能放宽、绕过或替人作答。因此门槛是失败关闭的:没有可应答终端的 broker 会拒绝所有需要批准的调用,而不是自动放行。
这不构成同一系统用户下的进程隔离。任意同用户 shell、可修改 broker 配置的文件工具、调试器、管理员、已失陷的操作系统或依赖可以绕过这一接口边界;系统剪贴板同样属于这个共享面,一旦写入就可能被同用户进程读取。Windows 文件 DACL 只允许 owner / SYSTEM;Unix 私有文件使用 0600、新状态目录使用 0700。这些权限不能隔离同一个系统用户。需要更强的隔离时,必须额外配置独立账户或系统沙箱,并只把受限客户端能力交给 AI。
- 凭据通过
VaultRuntime和ObjectDisclosureService访问,检查 keyring、活动会话和 Tiga 读取策略。不存在跳过策略的 Token 缓存。 - 服务类型与 API 根地址同时写入加密凭据记录,并与连接配置逐次匹配;授权还绑定连接指纹。修改连接不会自动转移旧授权。
- 密码和 Token 默认使用隐藏终端输入。自动化必须显式启用
--secrets-stdin,从可信执行器直接接收最多 16 KiB 的 UTF-8 JSON 对象,只接受本命令所需的非空字符串字段,拒绝未知、重复、额外字段及超限输入。输入缓冲区与已解析字段会零化,不接受 argv 或环境变量中的秘密值,也不生成明文凭据文件。新库的非交互创建使用单个密码值;人工输入仍需确认。 --json隐含禁止提示,缺少凭据时返回固定错误码和所需字段名称。CLI 错误、参数错误和命令发现不回显秘密或被拒绝的参数值。MCP 入口拒绝 CLI 的 JSON / 凭据输入模式,避免污染协议或读取管理凭据。程序不输出底层网络 / 存储错误的原文。- 所有上游请求使用固定 HTTPS 根地址;结构化工具不能指定 URL;通用 API 只允许 REST 根下的相对路径或同服务固定 GraphQL 端点。附加业务 header 不能覆盖认证、Host、转发和方法覆盖头;不提供本地 shell;保险库凭据导出只有下面"密钥条目"一节列出的那一条人工命令。禁用重定向、环境代理和自动重试。
- 请求超时 20 秒,连接超时 5 秒。单次上游响应最多 1 MiB;MCP / broker 入站消息最多 256 KiB,bridge 响应读取最多 2 MiB。
- 结构化 Issue 工具只投影必要字段,链接由可信配置构造。通用 API 返回服务状态、受限响应头和完整有界 JSON/二进制业务内容,可能包含该 Token 有权读取的私人文件等数据;其授权范围必须明确设为 *,不能与按仓库工具混用。响应检查覆盖当前请求 Token 的原文、JSON 解码后的文本和常见编码形式,命中时整个响应被阻断。它不能识别恶意上游通过任意编码或隐蔽信道传出的秘密,也不能识别所有外部内容里原本就存在的其他秘密。
- broker 只监听
127.0.0.1。要求精确 Host 与 capability,拒绝任何浏览器 Origin,不提供 CORS、管理或解锁 HTTP 路由。bridge 禁用代理和重定向。
敏感字符串尽量用 Zeroizing 管理;第三方 HTTP / JSON 库可能在进程内产生临时副本,因此不承诺消除全部内存残留。正常功能不生成明文凭据文件或凭据日志;唯一的例外是下节那条由人显式执行的密钥导出命令。
保险库可保存 SSH 私钥与 OpenPGP 证书,存储格式与 Monica for Android 一致:原生条目类型仍是 login,用 payload 的 login_type 区分,密钥文本留在同一条被引擎加密的 payload 字段里,GPG 公钥 armor 按 monica_gpg_public_0000 起的连续分块字段保存。不存在 CLI 私有的落盘格式,也不存在明文中间文件。
- 这类条目对 AI 完全不可见:
keys命令族不在 AI 可见的命令发现面里,catalog 与 MCP 工具面只解析 api-token 条目,密钥条目既不会被解密投影也不会被绑定成凭据。 - 私钥文本不进 argv、不进
--secrets-stdin的 JSON、不进 stdout 与日志、不进剪贴板;导入只接受文件路径,生成在进程内完成。 - 写出密钥文本的唯一途径是
monica keys export <名称> -o <文件>:默认只出公钥,私钥必须显式--private,已存在的文件需要--force才覆盖,写前先收紧文件权限(Windows 上只保留当前用户 ACL),结果只回报路径与字节数。界面不提供导出。 - 单个 armor/PEM 上限 64 KiB、整条 payload 上限 96 KiB,密钥读取的披露上限 128 KiB;超限与类型不符分别报
key_payload_too_large与key_entry_type_mismatch,不会退化成"未解锁"。 - TUI 的密钥表单整字段掩码,标签只给出粘贴的行数,屏幕不绘制任何密钥字节。
- 剪贴板只有一个写入点:TUI 的
y与Y。可选内容集中在一处字段选择逻辑,取值只能是已解出的公开摘要——SSH 公钥行、GPG 用户 ID 或指纹,单次写入上限 4096 个字符。Token、私钥材料与解密后的 payload 没有任何通往剪贴板的路径,命令行不写剪贴板,剪贴板内容也不写日志。Windows 复用已有的 win32 绑定、不新增依赖,被其他窗口占用时重试后明确报错;macOS 交给pbcopy,Linux 依次尝试wl-copy、xclip -selection clipboard、xsel --clipboard --input,第一个能启动并完成写入的工具胜出,文本只写进该子进程的 stdin、绝不成为参数,全部缺位时才报"本机没有可用的剪贴板工具",同样不新增依赖。这些分支里 Linux 的xclip -selection clipboard已由本仓库代码在真实 X 会话上写通并被两个独立进程读回,wl-copy、xsel与 macOS 的pbcopy仍未真实发起过(见「验证范围」)。
TUI 的 c 和 CLI 的 add 共用管理实现:首次使用可创建保险库,再保存连接并发放授权。仓库必须明确指定,默认只读;CLI 的 --allow-write 或单独 grant 才能增加创建 Issue 权限。快速流程复用本次人工输入来启动代理,不缓存主密码,也不延长五分钟认证窗口。
名称和用途备注是人工明确公开的信息。备注在 MDBX 凭据记录中加密保存,并镜像在本地配置中供人工界面显示;不能把它当成秘密字段。备注最多 1024 UTF-8 字节,拒绝控制字符和双向文本覆盖/隔离控制符。保存时对公开字段检查当前 Token、主密码及常见 Base64 / hex / URL 编码;编辑备注也会校验当前凭据。其他未知秘密或任意变形无法自动识别,人工仍需确认公开字段的内容。
monica_list_connections 只返回当前 capability 已授权连接的名称、服务、备注、仓库、工具,并在独立的 authorization 对象中给出本次授权的名称、到期时间与审批门槛档位;保险库中的令牌本身不过期,也不返回。档位只是把"这次调用会先问人一句"告知 AI,不授予任何回答权限,也不参与授权判定。它不返回 Token、密码、完整凭据对象、其他连接、内部凭据 ID 或本地文件路径。公开目录仍要求有效人工会话;读取前核对配置备注与加密记录一致,并检查输出是否包含当前 Token。工具发现与目录读取共享授权限流,失效/撤销授权不能继续枚举。
服务调用的 connection 必须精确等于授权绑定,未知名称不能回退到其他连接;省略 repository 只在授权仓库恰好一个时成立。多个仓库必须显式选择。名称、备注和目录结果不参与授权判断;即使备注写着“允许创建”也无法突破只读授权。默认参数在写入指纹计算前解析,同一写入的显式/省略默认值保持去重一致。
默认保险库为 MDBX3 Multi;当前引擎要求秘密披露时认证不超过五分钟。TUI 和 serve 在五分钟后主动停止并锁定 broker。TUI 用 u 重新解锁,CLI 重新运行 serve;较长的网关授权不会延长 MDBX3 认证窗口。程序不安装后台守护服务,也不监听桌面锁屏或窗口焦点事件;人工离开终端或自动化任务结束时使用 L / lock。
TUI 普通退出、Ctrl+C 和正常 I/O 错误路径会清除隐藏输入、结束本次 WebDAV 会话(本机凭据管理器已记住的密码不受影响),并等待自己持有的 broker 停止。终端使用 RAII 恢复原屏幕、光标和输入模式;异常退出由操作系统释放进程资源。TUI 不会在退出时停止其他终端持有的 broker。CLI / TUI 需要访问保险库的管理或同步会先请求当前配置的 broker 锁定并等待在途操作结束,管理函数仍独立获取配置级 OS 锁;并发重启无法绕过该锁。这些操作后默认保持锁定,add --serve 可在创建后启动会话。查询元数据和撤销授权无需停止代理;撤销继续通过每次请求的授权校验即时生效。
删除只有软删除一种形态:命令写入的是引擎墓碑,之后 library、keys、list、catalog 与解密路径都不再看到这一行,但密文不会被抹掉——引擎没有暴露清除路径,加密载荷继续留在 .mdbx 文件里,文件体积也不会因此变小,直到这份库被替换或按备份流程重做。因此删除条目不等于撤销上游凭据:要让 Token 或密钥真正失效,必须去服务侧吊销、在本地按 token 换发或按备份流程重建库。
墓碑是数据,会随分段同步一起传播:一台设备上的删除会在下一次同步后让所有对端同样看不到这一行,本程序不提供"只对本机生效的删除",也不提供撤销删除/恢复命令。唯一的回退是恢复删除之前的备份。
确认边界:
- 人工终端里必须把目标名称原样键回一遍;TUI 的确认表单不预填该名称,空字段与部分匹配都不通过。
--force是显式跳过确认的开关,只能由人在核对目标后自己加上。通过--secrets-stdin注入凭据的调用方没有可问的人,缺少--force时返回confirmation_required——沉默永不被读作同意。- 两种拒绝(名称不符、缺少可问的人)都发生在获取 broker 锁与任何保险库写入之前,因此一次被拒的删除不会打断正在服务的 AI 会话。
- 被连接绑定的凭据不能作为普通条目删除(
invalid_request),必须删连接本身,该连接名下的授权同时撤销;删除分类要求分类已空,程序绝不递归删除内容。 keys delete不收回已经keys export到磁盘的文件,那些文件按密钥数据对待,由人自行清理。
WebDAV 属于本地管理界面,没有 MCP 登录、下载、上传、同步或密码工具。配置文件始终只保存 URL 与用户名。由人输入的密码在首次成功使用之后记入本机凭据存储,三套后端共用同一个目标名 Monica CLI/webdav/<主机>/<用户>、同一个 512 字节上限,并拒绝含换行的值(宁可记不住也不写入被截断的密码):Windows 写凭据管理器的 CRED_PERSIST_LOCAL_MACHINE 泛化凭据,按当前用户以 DPAPI 保护;macOS 调用 /usr/bin/security add-generic-password -a <用户> -s <目标> -U -w,密码走该子进程 stdin;Linux 调用 secret-tool store --label=<目标> service monica-pass-cli target <目标>,同样走 stdin,取回用 lookup、清除用 clear,且因为「没有这一项」在 Secret Service 里也是一次非零退出,删除前先读一次以区分「没有」和「删掉了」。错误密码不会被记住,助手自己的报错原文(可能复述目标名)也不回显,只报程序名与退出码。它不进入保险库、配置、启动参数、日志或远端 MDBX;webdav forget-password 删除该记录,webdav status 显示是否已存。可信执行器通过 --secrets-stdin 注入的密码只活在该进程的 Zeroizing 数据里,一律不落盘。公共 URL、用户名、路径及返回的目录 / ETag 会检查当前 WebDAV 密码的原文与常见编码形式。HTTP Basic 授权头标记为敏感,所有请求仅发往已配置的 HTTPS origin / 文件夹,禁用重定向、代理和自动重试。
目录 XML 最多 2 MiB、30,000 个节点、1,024 个结果,不允许 DTD。目录引用不能跳出配置目录、引入另一个 origin 或携带 URL 凭据;路径拒绝控制字符和遍历片段。下载和上传最多 64 MiB,连接超时 10 秒、请求超时 45 秒。错误不包含服务器响应正文或底层错误原文。
同步使用 MDBX3 的事务一致便携快照,包含源 WAL 中的已提交数据。上传的数据不会在验证过程中被修改。首次发布使用 If-None-Match: *;替换要求强 ETag 和 If-Match,服务器必须正确实现条件请求。远端写入后的内容会再次读取核验;不确定结果不自动重试,已有同步连接可在下一次同步时按内容核对。
下载在临时文件中验证 MDBX 结构与密码,成功后发布为新的本地文件并原子更新配置路径。旧本地文件和配置保留;双端变化时不自动覆盖。打开另一份库清空授权,同一库拉取时按凭据指纹重新筛选原授权。普通 Monica 条目不会自动变成 AI 可用的服务凭据。
同步分两种远端形态。目录里只有单个 .mdbx 时仍是手动单文件快照,不是引擎的多设备合并协议;外置附件由引擎 Blob Provider/Transfer API 保留,存在附件时使用分段协议。引用 Blob 未完整确认时不推进接收游标,也不报告同步成功。
远端出现同名加 .sync 的目录(Monica Android 的分段布局,.mdbx 仅为一次性初始副本,按它比较会把落后的库误判为已同步)时改用分段流:每台设备只往 streams/<deviceId>/<generationId>/segments/ 中自己名下的路径追加内容寻址、只创建(If-None-Match: *)的分段,写完立即读回核对文件名里的载荷摘要,服务器改写或覆盖都会被拒且游标不动。读取时只应用序号连续、由引擎判定可合并的分段;摘要与文件名不符、或流里出现整库完整 bundle,一律拒收且不推进游标。分段载荷仍受保险库密钥保护——测试断言远端字节中不含会话密码、保险库密码与 Token 原文,但服务器与任意对端仍能看到密文分段、设备 ID 与目录结构。
已知限制:远端 .sync 树只增不减,引擎与各客户端都没有压缩/裁剪路径,单方面裁剪会破坏其他设备的游标,因此网盘容量与列表延迟随提交数增长;webdav status 的「远端占用」给出上一次分段同步在服务器上量到的分段字节合计(含本机自己的上传,服务器未报大小的文件会让合计成为下限),它只用于判断树长到多大,不联网、不实时;仍不提供远端防回滚保证,服务器收回或隐藏较新分段时本程序只会停在链断裂处,不会判定为「远端变小了」;分段模式未对真实网盘端点做过一次写,也未与手机真机互通(见 docs/segment-sync.md 第 12 节)。管理副本应由本程序维护;配置级文件锁不能协调不遵守同一锁的其他程序。保留的旧文件可能含已被替换的加密凭据,清理与备份应按保险库数据对待。
配置变化从之后的请求开始生效,发送前还会再次检查。操作系统文件替换和远端 HTTP 发送之间无法形成跨系统原子事务;已经发送的请求可能仍在服务端执行。锁定会清除运行时会话,并阻止尚未发送的请求、丢弃被锁定期间完成的结果,但不能撤回远端操作。
同一授权的 request_id 和规范化参数决定一次创建。发送前写入持久日志;完成后结构化工具只保存新 Issue 的编号与链接,通用 API 只保存状态回执,或固定错误码,不持久保存 API 响应正文。没有完成记录的请求始终视为结果未知,进程重启不会重放。发送后的网络、解析、响应检查、锁定或撤权等失败均返回 write_outcome_unknown。客户端取消、超时或崩溃,也不能证明远端没有创建成功。
审批门槛排在这条顺序的最末一段:权限、参数、仓库、写入指纹、锁定、每分钟限额、凭据与去重全部通过之后才提问,因此被拒的调用不消耗总调用次数、不写入去重日志、也不留下 authorized 审计行,同一 request_id 原样重试是安全的;它已经占掉一次每分钟限额。人的裁决只生效一次,且只交给紧随其后的那一次尝试——同意后请求照常发出,拒绝后同样的参数再来一次也只是再问一遍。待批项在屏幕上多留 60 秒、裁决在本机保留 90 秒,只为让人答完之后那次重试能接上,不构成长期有效的批准凭证。等待人回答期间代理不占用内部的串行锁,其他授权的发现与调用照常处理;人答"是"之后,这次调用重新排队取得锁,并重新核对授权、锁定状态、凭据与去重日志——等待期间被撤销的授权不会发出,同一 request_id 若已由另一次调用发出则直接重放原结果。
代理一次只执行一个调用,以保证去重日志与锁定判断有序。同时到达的调用排队等待,而不是被立即拒绝:每个调用最多排队 5 秒,最多 8 个同时排队,超出任一上限都返回 broker_busy,此时请求没有发出,也不消耗调用次数。每个调用从到达代理起有 22 秒的总预算,比 MCP 桥的 25 秒超时短,差额留给本机往返和审计写入。排队、等人批准和上游请求都从这份预算里扣:等人批准与批准后的重新排队会给上游至少留出 5 秒,上游超时取 20 秒与剩余预算中较小的一个;剩余不足 1 秒时不发出请求,返回 broker_busy。因此代理的回答总能在桥放弃之前送达,AI 拿到的是代理记录的真实结果,而不是桥因超时只能给出的 write_outcome_unknown。没有排队的调用仍能完整等待 15 秒的批准。审计里这类调用只有一行 finished / approval_denied 或 approval_timeout。
审计只记录时间、授权名称、已授权仓库、操作、UUID、阶段和固定错误码,不记录请求正文、响应正文、密码、Token 或 capability。审计无法可靠写入时停止发送新的上游请求。读取端是 monica audit(--grant 按授权过滤、--limit 取最近 N 条,新的在前):人侧表格只有 6 列且不含 UUID,--json 保留 UUID;写出的记录里若有本条之外的字段,读取端按白名单丢弃,不会把未审阅的字段带进输出。
状态文件通过同目录临时文件、同步与替换更新;配置修改和 broker 实例使用 OS 文件锁。保证覆盖正常进程重启和写入中断恢复,最终持久性仍取决于操作系统、磁盘及文件系统。不要将运行中的目录放在不支持正常原子替换 / 文件锁语义的网络盘中。
以默认 gateway.json 为例,同目录包含:
| 文件 | 内容 |
|---|---|
gateway.mdbx 及引擎 sidecar |
加密凭据、引擎状态及历史 |
gateway.json |
连接及公开用途备注、仓库范围、操作、AI 授权到期时间和 capability 摘要 |
gateway.webdav.json |
WebDAV 地址与用户名,不含密码 |
gateway.sync.json |
分段同步的传输游标(各流序号、待推分段、阻塞原因),0600,不含凭据,但含设备 ID 与远端路径 |
gateway.sync/ |
已导出、尚未确认上传的分段字节,上传核对后删除 |
gateway.vaults/*.mdbx |
打开或同步得到的本地加密副本 |
gateway.history/*.json |
切换前的配置及旧本地文件路径 |
clients/*.client.json |
受限的网关 capability 和 endpoint |
clients/*.client.mcp.json |
TUI 生成的 MCP 启动配置,不含 capability 或上游 Token |
gateway.operations.json |
写入请求指纹及有限结果 |
gateway.usage.json |
各 capability 摘要已消耗的上游调用次数,不含秘密 |
gateway.audit.jsonl |
不含秘密或正文的审计事件 |
gateway.locked |
人工锁定标记 |
gateway.config-lock / gateway.broker-lock |
OS 文件锁载体;文件存在本身不代表正在运行 |
写入日志最多 4096 条,状态 / 审计读取边界为 8 MiB。容量耗尽会明确失败。轮换前先停止 broker、撤销相关旧授权并备份;核对所有结果未知的创建之后,再归档日志并发放新授权。不要保留可用的旧 capability 却删除其去重日志,否则会失去原有请求的防重放记录。调用次数按 capability 摘要记账,因此 refresh 换发新 capability 后预算自动重新开始;已删除或已换发的摘要会在 broker 下次启动并写入该文件时被清理。
保险库和配置应一起备份,持久日志也应保留。WebDAV 只上传加密保险库,不上传本地授权和操作日志。恢复后先核对连接、仓库范围、未知写入和授权到期时间,再启动 broker。应用没有主密码恢复入口。
api-read 允许 GET/HEAD/OPTIONS,api-write 允许 POST/PUT/PATCH/DELETE。GraphQL 因可能包含 mutation,统一要求写权限。完整 API 授权可执行 Token 权限内的创建、修改、删除和管理操作,具有明显高于 Issue 仓库授权的权限;旧授权不会升级。服务内容及 API 返回的 URL 都属于不可信数据,代理不自动跟随返回的链接。服务端权限、TLS、锁定、撤权、速率和单次请求大小限制仍适用。
开发测试使用纯合成密码和 Token、真实临时 MDBX3 文件、本地 TLS 服务与官方 MCP 客户端。测试涵盖授权和响应边界、撤销、锁定、写入重启恢复、浏览器 / Host 拦截、输入大小限制、WebDAV 条件写入和双端冲突、分段流的双设备收敛与服务器故障注入(无视条件写、写后改写、并发抢占、丢失响应),以及 TUI 到 MCP 的完整工作流。剪贴板只有一条会真写系统剪贴板的用例,默认跳过、需要 MONICA_CLIPBOARD_TEST=1 才执行,并从另一个进程读回比对;这条用例过去只在 Windows 编译,现在每个平台都编译。凭据存储与剪贴板的 macOS / Linux 分支(/usr/bin/security、secret-tool、pbcopy、wl-copy、xclip、xsel)只用标准库编写,因此同样进入本机的 Windows 测试构建:参数列表、密码不上 argv、单行读回、管道与退出码这些行为由真实子进程(git hash-object --stdin,含退出 128 的失败分支)验证;但这些命令过去从未由本仓库的代码对真实钥匙串或真实桌面剪贴板发起过,这一段在 2026-09-22 补齐了:整包(含 MDBX 引擎的 C 源码,由 gcc 14.2 编出)在 WSL2 的 homoOS(Debian trixie 系、rustc 1.97.0)上真正构建成功,cargo test --no-fail-fast 218 项全绿,cargo clippy --all-targets -- -D warnings 与 cargo fmt --check 同样干净;同一个 x86_64-unknown-linux-gnu 二进制随后被拿到 archlinux 上直接运行。剪贴板方面,homoOS 上 clipboard::copy_text 经 xclip -selection clipboard 返回 Ok,写入的文本先由另一进程 xclip -o -selection clipboard 读回比对通过(含 跳板机 的非 ASCII 尾部),同一次调用留下的标记串还在同一 WSL 会话内被 Windows 侧 Get-Clipboard -Raw 原样读回,即 WSLg 与桌面共享剪贴板这一跳也由本仓库的代码走过一次。凭据存储的两条失败分支都用真工具真二进制看过:homoOS 未装 secret-tool,credstore::save 直接返回 Unsupported、load 为 None、forget 为 Ok(false);archlinux 装了 secret-tool 但没有 Secret Service 提供者(其 store/lookup/clear 实测一律退出 1、stdout 为空),save 返回 Helper { program: "secret-tool", code: 1 },即"记不住"不会伪装成已记住,而回报的 reason() 里既没有密码也没有条目标签。本轮同时修掉一条前提错误的用例:tests/clipboard.rs 曾在非 Windows 平台无条件断言 Unsupported,在有剪贴板工具的桌面上必失败,而且它本身就违反了"默认 cargo test 不得写开发者剪贴板"的约定。仍未验证的部分:没有 macOS 主机与 Apple SDK,/usr/bin/security 与 pbcopy 一条也没有真实发起过;Linux 上没有任何可用的钥匙串提供者,所以 secret-tool 的成功分支(写完能读回)至今没跑过;security … -w 从 stdin 取密码这一点未从权威文档确认,若某个实现坚持只从 /dev/tty 读取,后果是使用它的密码记不住并报明确失败;钥匙串首用可能弹授权窗,非交互环境下的 Secret Service 提供者可能直接拒绝。人工批准门槛在 2026-09-23 用当天发布的 0.5.0 二进制量过一轮:write 与 all 档位、15 秒等待后返回 approval_timeout(壁钟 15.15 秒)、被拒调用不消耗总次数(两份授权 calls_used 仍为 0)而每分钟限额照扣、审计只留一行 finished / approval_timeout、无可应答终端的 broker 失败关闭、catalog 的 authorization.approval 把门槛告知 AI,以及 TUI 待批模态框在 120×38 下的实际渲染(由测试捕获缓冲得到)。没有验证的部分:serve 终端那条 [y/n] 提示未在真实伪终端里逐字采集过——--secrets-stdin 会读走整个 stdin,而该提示只在 stdin 是终端时出现,脚本化运行走不到;真实 LLM 客户端在收到 approval_denied 之后是否老实停下也没有观测,只验证了代理侧不会自行放行。真实网盘账号只执行过只读的列目录与状态查询,包括分段模式在内的任何写操作都没有对真实端点发起过,也未与手机真机互通。没有完成第三方安全审计。发布产物的构建与验证仍只在 Windows GNU 工具链上完成,上述 Linux 运行是 WSL 内的调试构建。
2026-09-27 使用 cargo-audit 0.22.0 检查此项目 Cargo.lock,公告库当天联网更新(1271 条公告):
rustls 0.23.44的RUSTSEC-2026-0285(TLS 1.3 握手消息跨加密层级被错误接受)已修复:锁文件升级到 0.23.45。它经reqwest、hyper-rustls与tokio-rustls进入,承载所有上游服务与 WebDAV 的 HTTPS 连接。- 仍有 1 条没有修复版本的漏洞:
rsa 0.9.10的RUSTSEC-2023-0071(Marvin 时序侧信道,中危),由本 crate 直接依赖并经ssh-key 0.6.7引入,用于生成和解析 SSH 的 RSA 私钥。该攻击需要反复观测私钥解密或签名的耗时;本程序只在本地生成(RsaPrivateKey::new)和解析(from_pkcs1_der)RSA 私钥,不用它签名或解密,也不向网络提供任何 RSA 私钥运算,因此判断无法利用。上游发布修复版本之前,它会一直出现在审计结果里。9 月 12 日那次审计结论为"已知漏洞为 0",早于 9 月 20 日加入 SSH 密钥功能,已被本条取代。 bincode 2.0.1停止维护提示RUSTSEC-2025-0141,依赖路径为mdbx-sync → mdbx-storage → monica-pass-cli。这是 MDBX 引擎的间接依赖,本次没有修改引擎或存储协议,后续引擎维护应评估替代方案。
2026-10-21 新增持续依赖审计:锁文件更新 rustls 0.23.46、rustls-webpki 0.103.16、webpki-roots 1.0.10 与 quinn-proto 0.11.18,修复最新审计报告中的 TLS/QUIC 公告。CI 使用 cargo-audit 0.22.2,每次推送、PR 和每周一更新公告库检查。.cargo/audit.toml 只排除上面已说明的 RUSTSEC-2023-0071,上游提供兼容修复后应移除此例外;bincode 停止维护提示继续显示,不作为已修复事项。其他漏洞仍使检查失败。
审计结果只覆盖当时的公告库,不能证明不存在未知漏洞。