背景
项目说明与 persistence.rs 文件头仍描述 Keychain-backed credentials,但当前实现实际上把凭据写入本地 JSON 文件。这个 issue 只跟踪 凭据存储策略与威胁模型不一致,不混入 QA XSS 或 provider status 修复。
现状
文档 / 文件头语义:
- 凭据应存在 Keychain / 平台凭据存储。
- plaintext JSON 应只是 Swift legacy fallback / 首次迁移入口。
实际实现:
- macOS / Linux 写
~/.openless/credentials.json
- Windows 写
%APPDATA%/OpenLess/credentials.json
- Unix 下设置父目录
0700、文件 0600
CredentialsVault 注释明确说“不走 Keychain”
代码证据
openless-all/app/src-tauri/src/persistence.rs:1-13:文件头描述 Keychain-backed vault
openless-all/app/src-tauri/src/persistence.rs:108-113:实现注释改为纯 JSON,故意不用 Keychain
openless-all/app/src-tauri/src/persistence.rs:236-252:凭据路径指向 JSON 文件
openless-all/app/src-tauri/src/persistence.rs:289-304:写入 JSON 并设置权限
openless-all/app/src-tauri/src/persistence.rs:658-664:CredentialsVault 不再使用 Keychain,仅保留 service name 常量
风险
0600 / 0700 可以降低跨用户读取风险,但不等同于 Keychain / Credential Manager:
- 同用户恶意进程、备份同步、误打包、日志/诊断收集路径更容易接触 plaintext 文件。
- 一旦 WebView 注入或本地低权限链路能调用 app command,plaintext 存储会放大影响。
- 文档与实现不一致会误导后续安全设计。
需要决策
二选一即可,不要长期保持“文档说 Keychain、实现写 JSON”的中间态:
- 恢复平台凭据存储,并把 JSON 变成只读一次性迁移来源。
- 明确产品选择 plaintext local file,并同步更新 AGENTS / docs / UI 文案 / threat model,同时减少前端读取 raw secret 的能力。
验收标准
关联
背景
项目说明与
persistence.rs文件头仍描述 Keychain-backed credentials,但当前实现实际上把凭据写入本地 JSON 文件。这个 issue 只跟踪 凭据存储策略与威胁模型不一致,不混入 QA XSS 或 provider status 修复。现状
文档 / 文件头语义:
实际实现:
~/.openless/credentials.json%APPDATA%/OpenLess/credentials.json0700、文件0600CredentialsVault注释明确说“不走 Keychain”代码证据
openless-all/app/src-tauri/src/persistence.rs:1-13:文件头描述 Keychain-backed vaultopenless-all/app/src-tauri/src/persistence.rs:108-113:实现注释改为纯 JSON,故意不用 Keychainopenless-all/app/src-tauri/src/persistence.rs:236-252:凭据路径指向 JSON 文件openless-all/app/src-tauri/src/persistence.rs:289-304:写入 JSON 并设置权限openless-all/app/src-tauri/src/persistence.rs:658-664:CredentialsVault不再使用 Keychain,仅保留 service name 常量风险
0600/0700可以降低跨用户读取风险,但不等同于 Keychain / Credential Manager:需要决策
二选一即可,不要长期保持“文档说 Keychain、实现写 JSON”的中间态:
验收标准
read_credential这类 raw secret 返回路径经过重新评估,不默认暴露给所有窗口。关联