Safe Haven 中文文档 下载 App

Safe Haven 源码仓库入口和 .safehaven 验证机制

为什么要做这个验证

Safe Haven 有五层信任机制,第二层"已验证源码"是可信度最高的一个——它证明了"这个 Safe Haven 应用条目和这个源码仓库是同一个开发者管的"。

怎么做?不是让开发者填一个表单、也不是 OAuth 登录 GitHub。Safe Haven 选择了一个更"代码即文档"的方式:让开发者在自己的仓库根目录放一个叫 .safehaven 的文件,文件里写一个 token。Safe Haven 服务端定期去抓这个文件,比对 token 是否匹配。

具体步骤

第一步:Safe Haven 后台生成 token

开发者在 Web 管理门户(store.colourswift.com 的开发者后台)登记一个新应用条目。登记时需要提供:

登记完成后,Safe Haven 后台生成一个唯一的仓库验证 token(随机字符串),展示给开发者。这个 token 只有这一个作用——放在仓库里证明所有权。

第二步:开发者在仓库根目录放 .safehaven

拿到 token 后,开发者在自己的源码仓库根目录创建一个叫 .safehaven 的文件(无扩展名,文件名就叫 .safehaven),文件内容就是那个 token。

GitHub 上直接创建:点 "Add file" → "Create new file",文件名写 .safehaven,内容贴 token,提交。GitLab 和 Codeberg 同理。

第三步:Safe Haven 后台定期抓取比对

Safe Haven 服务端后台有定时任务,会去抓每个登记了仓库地址的应用的 .safehaven 文件。抓取用的是各 Git 托管平台的 raw file URL,格式分别为:GitHub 用 raw.githubusercontent.com 拼接仓库 owner 和名称及 main 分支路径;GitLab 用 gitlab.com 的 raw 路径;Codeberg 用 codeberg.org 的 raw/branch/main 路径。

注意三个平台的 URL 里分支名都用的是 main——如果开发者的仓库默认分支叫 master,可能需要改一下。

抓到文件后,Safe Haven 把文件内容和登记时存的 token 做比对。完全匹配→ 应用条目的 trustLevel 字段从 unverified 变成 verified_source,详情页亮起"已验证源码"标志。

这个机制的安全假设

Safe Haven 的验证机制基于一个简单但关键的假设:

能在仓库根目录创建 .safehaven 文件的人,就是这个仓库的管理员。

这个假设在绝大多数情况下成立。攻击者如果能往别人的仓库根目录写文件,说明他已经拿到了仓库的管理员权限——而拿到管理员权限之后能干的坏事远比伪造一个验证 token 严重。所以这个验证机制在实际安全上是有效的。

平台差异

GitHub、GitLab、Codeberg 三个平台的 raw file URL 格式不一样,但 Safe Haven 都处理了。目前不支持其他 Git 托管平台——开发者如果用 Bitbucket、SourceForge 等,需要先把源码镜像到这三个之一。

社区贡献的应用也能认领

如果一个应用是社区贡献进来的(打上了 unverified 标签),原始开发者发现后可以去 Safe Haven 的 Web 门户认领它。认领流程也是一样的:在仓库根目录放 .safehaven 文件,等 Safe Haven 后台抓取比对。认领成功后,条目的 trustLevel 会更新,F-Droid 来源的应用还需要额外提供签名哈希(因为 F-Droid 的 APK 是 F-Droid 自己签名的,认领后要切成开发者原生签名)。

token 会过期吗

官方文档没提 token 过期机制。这意味着 token 一旦生成就长期有效——如果开发者泄露了 token,理论上可以被人用来伪造验证。但 token 是放在公开仓库里的,所以不存在"泄露"的问题——任何人都能看到它。这也是为什么 token 不做过期:它本来就是公开的,放在仓库里本身就是证明。

和其他商店的验证方式对比

商店开发者验证方式
Safe Haven仓库根目录放 .safehaven 文件
F-Droid通过标准流程提交,用 F-Droid 签名重打包
IzzyOnDroid开发者用自己的签名,验证可复现构建
Google Play开发者账号 + 签名密钥

Safe Haven 的方式最接近"开源世界"的做法——不依赖某个平台的身份体系,验证本身就在代码仓库里。