配置存储
配置存储提供跨设备的零知识加密CLI配置同步。您的配置在客户端使用内容加密密钥(CEK)加密,服务器永远无法看到明文数据。
解锁方式(密钥槽)
每个存储只有一个CEK,但会为每种解锁方式独立包装,类似LUKS的密钥槽机制。任意一个密钥槽都能打开同一把密钥,且可以随时添加或移除密钥槽,无需重新加密您的数据:
| 方式 | 说明 | 备注 |
|---|---|---|
| 通行密钥 | 支持PRF扩展的WebAuthn通行密钥 | 最强选项;由硬件保障安全 |
| 主密码 | 您自选的密码,经PBKDF2-SHA256拉伸(60万次迭代) | 无需支持PRF的硬件即可使用;同时支持无浏览器的CLI注册 |
| 恢复码 | 系统生成的 RC1-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX 格式代码 | 仅在创建时显示一次,请妥善保存 |
每种方式都走同一条流程:密钥槽产出一个密钥片段,与服务器持有的密钥片段结合后解开CEK。任何一方单独持有的片段都不足以解密,因此这三种方式都保持零知识特性:密钥槽的密钥片段永远不会到达服务器。
密钥槽在门户的配置存储页面统一管理。只希望允许硬件解锁的组织可以启用要求通行密钥策略,该策略会拒绝并撤销整个存储中所有非通行密钥的密钥槽。
解锁是按设备进行的:在新设备上解锁一次后,日常的CLI操作(push/pull)就无需再触碰通行密钥或输入密码。
先决条件
- 您的账户已启用双因素认证
- 若使用通行密钥方式:需要支持PRF的通行密钥提供商,例如FIDO2安全密钥(如YubiKey)、iCloud Keychain、Google Password Manager、1Password或Dashlane
- 浏览器:Chrome 133+、Edge 133+、Firefox 130+或Safari 17+
PRF要求仅适用于通行密钥这一种密钥槽。主密码和恢复码方式在任何受支持的浏览器上均可使用。
设置
- 在侧边栏导航至配置存储,然后点击设置配置存储
- 需求检查表验证您的浏览器、双因素认证和会话状态
- 点击开始设置。设置通行密钥槽时,您需要触摸安全密钥两次:
- 第一次触摸:注册通行密钥
- 第二次触摸:通过PRF派生加密密钥
- 设置完成,您的通行密钥密钥存储在操作系统的密钥环中
设置完成后,建议在配置存储页面再添加一个主密码或恢复码密钥槽,以免因认证器丢失或不受支持而被锁在外面。
PRF提供商兼容性
| 提供商 | PRF支持 | 平台 |
|---|---|---|
| YubiKey / FIDO2安全密钥 | ✅ | Windows 11、macOS、Linux |
| iCloud Keychain | ✅ | macOS 15+、iOS 18+ |
| Google Password Manager | ✅ | Android |
| 1Password | ✅ | Android、iOS |
| Dashlane | ✅ | 跨平台 |
| Bitwarden扩展 | ❌ | 开发中 |
| Windows Hello | ❌ | 不支持 |
无浏览器的CLI注册
没有浏览器的机器(服务器、CI运行器、执行器守护进程)可以通过主密码方式注册到已有的存储中:
rdc config remote enable --password
前提条件:
- 已通过门户配置好主密码密钥槽(配置过程需要浏览器持有密钥,因此这一步本身无法在无浏览器环境下完成)
- 拥有具备
config:enroll权限范围的API令牌,用于验证此次调用
注册操作只读取数据:CLI获取该密钥槽的公开KDF参数和已包装的密钥,在本地推导出密码密钥片段,并在设备上解开CEK。该操作只授予设备解密和同步配置的能力,不会修改存储本身。
启用与离线读取
rdc config remote enable 会将当前配置连接到存储。如果存储为空,启用操作会用您当前的本地配置为存储播种:本地资源会作为存储的第一个版本被推送上去,然后再拉取回来,以验证这一往返过程无误。如果存储中已有内容,启用操作会与其进行协调,而不是直接覆盖(如果确实存在分歧,除非您传入 --force,否则操作会中止)。
启用之后,配置会保留一份完整的读取缓存,采用与任何本地配置相同的机制进行静态加密,因此即使无法连接账户服务器,存储依然可用:
- 读取可离线进行。 缓存内容会附带过期警告输出到stderr,并标注缓存版本和时间戳(
cachedVersion/cachedAt)。 - 写入需要服务器,且在无法连接时会安全失败(fail closed)。 不存在离线写入队列:无法到达服务器的写入会直接报错并指明该服务器。只要写入命令成功返回,改动就已经在服务器上了。
- 来自两台机器的并发编辑会在资源桶(resource-bucket)级别通过拉取-重放-再推送(pull-replay-repush)解决,因此别处的同时编辑不会覆盖您的更改。
密钥轮换
轮换存储的CEK会以新的世代重新包装密钥:
- 恢复码在轮换后总是失效,请在轮换完成后重新生成并保存新的恢复码
- 主密码密钥槽只有在轮换向导中重新输入密码才能保留
- 停留在旧世代的密钥槽会被报告为过期,而不是报出难以理解的解密错误
成员管理
配置存储按组织划定范围。成员通过Web门户管理:
- 查看成员:配置存储 → 成员
- 添加成员:目前仅通过CLI(Web界面计划中)
- 移除成员:点击成员页面上的移除按钮(需要双因素认证 + 重新认证)
安全保护措施防止移除最后一个活跃成员或移除自己。
存储中的配置还会按团队划定范围,但这种划分是服务器端的访问控制,而非加密隔离:整个组织共用同一个CEK加密所有团队的配置,而某个成员能读取哪些团队的配置,由服务器强制执行。
安全性
- 零知识:服务器存储其无法解密的三重加密数据
- 分割密钥:解密需要您的密钥槽密钥片段(客户端)和服务器密钥(服务器)
- 轮换令牌:每次API调用使用新令牌;旧令牌自动销毁
- IP绑定:令牌在首次使用时绑定到您的IP
- 即时撤销:被移除的成员在30秒内失去访问权限
故障排除
| 错误 | 原因 | 修复方法 |
|---|---|---|
| PRF not supported | 认证器缺少PRF扩展 | 使用YubiKey、iCloud Keychain、1Password或Dashlane,或添加一个主密码密钥槽 |
| X25519 not supported | 浏览器版本过旧 | 更新至Chrome 133+、Edge 133+、Firefox 130+或Safari 17+ |
| Already configured | 您的组织已存在存储 | 访问/account/config-storage进行管理 |
| Config storage not configured | 服务器缺少blob存储 | 联系管理员配置R2/RustFS |
| Token expired | 24小时无活动 | 运行任意配置存储命令以刷新 |
| Cannot remove last member | 将永久锁定存储 | 先添加另一个成员 |
| Stale slot | 密钥槽早于上一次密钥轮换 | 重新添加该密钥槽(恢复码必须在每次轮换后重新生成) |