# Warden 密码库、网站填充与常用网站（1.9.62）

> 1.9.64 更新：常用网站统一账号/验证器，取消日常主密码，自动访问秘密加密保存用户数据云；旧库一次验证、不换密钥。整套部署不再具有独立主密码端到端保护。下文主密码仅内存/五分钟锁定等均为历史规则。

> 1.9.63 历史更新：[统一个人云](unified-personal-cloud.md)取代本篇 1.9.62 的部署和日常入口：统一在设置授权；记事本和普通书签使用自动访问数据区；独立验证器迁移入 Warden。原 AES-GCM 库保留作为迁移源。下文是原版本设计/加密边界，不能据此把记事本或书签重新锁在主密码后。


## 本轮决策与边界

2026-10-01 用户确认：插件保持闭源，复用 MIT Warden Worker 服务端，插件客户端独立实现公开的协议和加密格式。不包含 Bitwarden GPL 客户端或 web-vault；不是官方 Bitwarden 客户端，没有独立安全审计，不承诺相同安全级别。许可清单随本地包发布；发布者仍须履行第三方许可义务。

密码库改用独立 Warden Worker、D1 与 HeavyDo，部署于用户自己选择的 Cloudflare 账号。个人 MCP Worker/DO 不增加密码库存储。记事本、独立验证器和旧密码库继续原个人数据云与原主密码/恢复密钥。邮箱邮件仅本机或用户选择的网盘。本轮不改变 AI API、远程 MCP 的账号凭据同步，也不把密码库加入脚本、MCP 或 AI 能力。

| 数据 | 存放与使用 |
| --- | --- |
| 登录密码、网址、备注、分类、常用网站、关联 TOTP 种子 | 主密码解锁后在本机使用；加密条目同步用户 Warden D1 |
| 邮箱标识、KDF 参数、服务端登录验证值 | Warden 账号数据库，邮箱是密钥派生标识，创建后不改 |
| 本机连接地址、设备 ID、加密缓存与待同步队列 | 按插件账号作用域设备加密保存，不上传官方 |
| 主密码、解锁密钥、Warden access/refresh token | 主密码只用于本机派生；密钥与令牌只在后台内存 |
| Cloudflare OAuth 管理令牌 | 部署过程本机暂存，用完清除；不存账号备份 |
| 待保存的网站账号密码 | 后台内存最多两分钟，仅用户在插件来源弹窗确认后入库 |

服务端保存经过服务端加盐哈希的客户端验证值和主密码包裹的数据密钥，不拿明文主密码。D1 中条目业务字段是密文，但条目 ID、类型、日期等元数据不保密。用户自己的云账号被关闭、删除 D1 或丢失主密码仍会丢数据；必须保留可用本机副本及自行维护云端备份。Warden 本轮没有恢复密钥、改主密码、整库导出入口，不能拿旧库恢复密钥解锁它。

## 用户流程

1. 重载 1.9.62，进入「密码库 → 云端设置」，填一个固定邮箱标识；它不是邮箱登录密码。
2. 点击授权 Cloudflare，选择用户账号，部署/升级独立密码库。新增 Worker、D1、SQLite HeavyDo 和登录限速 binding；无 R2、公共网页密码库、附件或 Send 入口。
3. 部署完成后再点击「授权并连接 Worker」取得浏览器网站权限。首次创建需联网、至少十二字符主密码及确认；换机使用同一个插件账号、同一 Cloudflare 账号和邮箱标识重新部署/连接，会复用同名 D1，随后输入原主密码解锁，不能新建覆盖。
4. 保存账号后先在本机加密，再尝试云同步。离线解锁只支持已缓存库；待同步和冲突状态明确展示。用户回到管理页点击同步，不宣称自动定时同步。
5. 逐站授权后可打开保存的网址，选择账号填充；要在尚未保存的网站提示保存，可明确授予 HTTPS 全站权限。全站意向关闭后，已保存且已授权的网站仍可填充。网站不获得密码库列表或解锁密钥。
6. 管理页离开/隐藏时清理明文表单；Warden 后台仍允许网站填充，五分钟无操作自动锁定（在下次接口调用检查）。主动锁定、账号切换/退出和 service worker 重启均失去解锁状态。TOTP 计时轮询不延长闲置时间。

## 模块与消息入口

- `warden-crypto.mjs`：WebCrypto PBKDF2-SHA256、HKDF-expand、AES-256-CBC+HMAC-SHA256 Type 2 cipherstring；先认证再解密。PBKDF2 600000–2000000，仅支持 KDF 0；密钥非可导出。首建随机 64 字节用户密钥及 RSA 公私钥，私钥加密后提交。
- `warden-client.mjs`：HTTPS 根地址、禁止重定向、浏览器网站权限、请求超时、最大 8 MiB 响应。
- `warden-store.mjs` / `warden-sync.mjs`：按账号设备加密缓存、内存解锁、离线待同步、CAS 冲突与不确定请求核对。
- `warden-deploy.mjs`：Cloudflare OAuth、SHA-256 校验预编译部署包、保留已有 JWT Secret 和 D1 身份。
- `warden-migration.mjs`：旧库逐条复制，云端读回并核对账号/密码/网址；pending/conflict 不计成功；旧库不删。
- `vault-site-match.mjs` / `vault-autofill.mjs`：HTTPS 精确 origin（含端口，不猜子域），同源 form action，标签页/会话复核，限时弹窗票据。
- `vault-page.js`：ISOLATED 顶层表单填充，仅唯一可见密码框且能识别用户名时工作；不读取跨域 frame，不通过宿主 postMessage 传密码。
- `vault-popup.*`：插件来源原生小窗口，选择账号或确认保存/更新；不作为网页可访问资源。
- `views/vault.mjs`、`bookmarks.mjs`：Warden 管理；`private-library.mjs` 承接旧库、记事本与独立验证器。
- `background.mjs`：WARDEN 只接受管理页；VAULT_PROMPT 只接受插件提示页面；VAULT_PAGE 只接受本扩展顶层 HTTPS content script，不信任 userScriptId。

密码库不提供 SellerFeeds API。不得把条目、主密码或种子加入普通任务参数、数据中心、官网日志、机器人通知、AI 提示词。网站填入的账号密码必然会交给该网站自身；网页匹配不能防止合法网站本身恶意或被攻破。

## 同步和迁移规则

本机保存一条加密 pending。新建使用本机 localId 和 operationId 写入加密 metadata；响应丢失时先同步寻找同 operationId，不能直接重复创建。尝试过但未确认的记录先核对再允许编辑。修改带 `lastKnownRevisionDate`，服务端补丁使用严格日期与 SQL 条件 UPDATE；并发旧版本返回 409，不使用上游一秒容差。冲突用户选采用云端或保留两份，不自动覆盖。

删除是插件加密 metadata 中的逻辑墓碑，本轮不调用服务端永久删除接口。不声称其他兼容客户端会将此墓碑隐藏，也不声称全量支持官方客户端所有格式。常用网站是 SecureNote + 加密 site，关联 loginId 也是加密 metadata。个人库最多 1000 条。

旧库和新库须分别解锁；复制使用旧 ID 加密标记判重，必须完成远端确认再读回核对。任一步失败保留原条目与新库待同步记录，重试不直接覆盖旧库。旧 TOTP 的算法、位数、周期应保留；不支持的条目明确报错，不静默丢弃。

## 网站能力的实际范围

标准 HTTPS 同源登录 form：匹配账号选择、填充、真实用户提交时确认保存/更新。自动填充和自动提交逐条选择、默认关闭；明显验证码/OTP 框存在时不自动提交。SPA 自定义登录、跨域 iframe、多密码框、passkey、复杂多步骤登录不保证支持；无法确定时停止。保存提示不等于网站已确认登录成功，用户须自行核对。

选中关联常用网站后会打开正常标签页并提供匹配账号选择；不能保证无需用户操作即登录。填充前后复核 URL 与解锁 lease；网站字段变动后再检查同源 form。全站保存提示必须显式 browser permissions 手势授权，不能借已有脚本全站权限自动开启用户意向。

## 服务端与构建

固定 MIT 上游 https://github.com/qaz741wsd856/warden-worker ，commit `7a9f6b9e3cb46449f50df33d7577481ccb9f1b71`，Cargo.lock 保留。源码 `cloudflare/sellerfeeds-warden/upstream/`，仅 ciphers.rs 有严格 revision CAS 补丁。网关只开放当前客户端用到的认证/sync/ciphers 路由，禁跨网页 Origin，注册同时要求 SETUP_KEY、空库和精确 ALLOWED_EMAILS，缺少必需 binding 返回 503；请求 5 MiB 上限。

本地预编译使用 rustc 1.97.1、worker-build 0.8.5、wasm-bindgen 0.2.127、wasm-opt 130、esbuild 0.28.1（上游原工具链 1.91.1 下载未完成，本轮使用明确记录的已安装编译器，不修改其源码锁文件）。`scripts/build-warden.mjs` 产生固定模块及哈希 manifest；`scripts/build.mjs` 随插件打包，最终用户不用 Rust/Node。维护者重新编译：

```sh
cd cloudflare/sellerfeeds-warden/upstream
RUSTUP_TOOLCHAIN=1.97.1 worker-build --release --locked
```

需先安装对应 Rust wasm target 与 worker-build 0.8.5。许可清单由 `scripts/warden-license-manifest.mjs <cargo-metadata-json>` 生成，包含 Cargo.lock 依赖及构建/平台依赖；双许可证选择 MIT/Apache 等宽松选项，AND 许可同时保留。部署包中的 upstream 代码保持 MIT 通知，闭源客户端没有导入其客户端实现。

## 验收与未完成真实账号验收

- 独立 Node 密码学参考向量核对、改密文认证失败、离线读写、锁定/账号隔离、不确定创建恢复、同步冲突均有回归测试。
- `scripts/verify-warden-local.mjs` 使用**临时本机** Wrangler D1/HeavyDo 实际运行编译后的 Rust/WASM，验证创建、登录、密文保存/读取、并发 CAS（200/409）、refresh 与注册/Origin 防护。不能用真实用户库运行：首次要求空 fixture DB，只允许 127.0.0.1。
- Chrome 虚构数据界面已检查桌面布局；实际 vault-page.js 在受控 HTTPS 登录表单通过填充、URL 变更拒绝和跨域 action 拒绝检查（浏览器中模拟 runtime，不冒充已安装插件的端到端验收）；本轮不自动重载用户已装插件、不代部署用户 Cloudflare、不发布 GitHub/官网。
- 上线仍需用户本人部署后：Chrome 扩展端 OAuth/D1 权限、Worker 上传启动额度、新电脑同库解锁、真实网站填充/保存、断网同步、旧库迁移逐项核对。
