跳转到内容

身份和成员资格

bae 中没有任何账号系统。设备的身份是它为自己生成并保存在 OS 钥匙串中的 Ed25519 密钥对;公钥就是身份。谁属于一个资料库,由云端主目录中一组已签名记录表示;任何持有这些记录的人都可验证它们,它们不由服务器签发。这套机制来自 coven;本页说明 bae 如何使用它。

每个 owner 都会向云端主目录写入一条仅追加的已签名成员记录流:这个密钥以这个角色加入,这个密钥被移除。每个记录都链接到前一个,且每个 owner 都会签名一个头部来声明自己流的末端,因此提供商如果丢弃或重排记录,会被检测出来,而不会被相信。资料库接受的是每个 owner 已验证流的并集。

每次拉取时,每个 changeset 的作者都会对照该记录检查:由当前成员签名,且角色允许写入。来自已移除设备、从未加入的密钥,或签名无效的 changeset 不会应用。提供商存储这些记录,但不能伪造它们;只有 owner 密钥持有者能更改成员资格。

OwnerMember 都能读写资料库;owner 还可以批准和移除设备。bae 的创建设备是 owner,它批准的每台设备都以 member 身份加入。(底层机制中存在第三个角色,即只读 follower,bae 目前不会分配它。)

添加设备是一次双代码交换,中间有明确的人工验证:

  1. 加入设备生成自己的密钥对,并显示 join request:它的公钥、该密钥的短指纹,以及(对 OAuth 提供商而言)要与之共享文件夹的云账号。
  2. owner 解码该请求,两个屏幕显示同一个指纹。人检查它们是否一致;这一步会阻止被替换的 key。
  3. 批准会同时做三件事:授予新设备账号访问云端主目录的权限(消费者云上的文件夹共享、S3 上的嵌入凭据、iCloud 上的 CloudKit 共享),把资料库密钥封装给新设备的公钥,并签名一条加入它的成员记录。所有内容打包成 invite code
  4. 加入设备使用邀请,解封密钥,从最新快照启动,并开始同步。

邀请被封装给请求密钥:拦截它不会得到任何权限。

移除成员会追加一条已签名的移除记录,并把资料库密钥轮换到被移除密钥永远不会收到的新世代(见加密)。在可撤销访问的存储上,访问权也会被收回。已经同步到被移除设备上的内容仍在它那里;数据无法追回。轮换后的所有内容都超出它的可达范围。

恢复码有意绕过成员资格:它是云端主目录坐标加资料库密钥,放在一个持有者字符串中,用于在没有存活批准者时恢复你自己的资料库。它按需生成,在 Apple 平台上会自动存储在 iCloud Keychain 中,并且与资料库本身同等敏感。