ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

BongoCat 更新清单传输信封契约解析:ADR-0022 的字节级设计、边界约束与后续演化

BongoCat 更新清单传输信封契约解析:ADR-0022 的字节级设计、边界约束与后续演化 桌面应用【免费下载链接】BongoCat BongoCat — A cross-platform interactive desktop pet that brings fun to your desktop!项目地址https://gitcode.com/gh_mirrors/bong/BongoCat点击查看免费下载本文以仓库 docs/adr/0022-update-manifest-transport-envelope.md 为主体结合相邻 ADR 与bongocat-updatecrate 的源码与测试完整讲解 BongoCat 更新系统中签名 manifest 如何在 HTTP 传输层被无歧义地搬运这一核心问题为什么需要传输信封transport envelope、信封对 endpoint/body/header 施加了哪些精确约束、UpdateManifestEnvelope的职责边界如何划分以及这套契约在 ADR-0025 / ADR-0029 / ADR-0034 中如何演化与退役。读者读完可获得一份可复用的离线验签 网络传输解耦契约设计清单。一、导读一份只负责无损搬运的传输契约BongoCat 将自动/手动更新列为首发行为但更新的信任判断验签、版本、target、hash必须建立在与网络层完全隔离的基础之上。ADR-0021 已经用 detached Ed25519 签名固定了先验签、后解析的离线验证边界但彼时尚未定义网络响应如何把 key ID、detached signature 和原始 body无损地交到验签器手里。ADR-0022Update Manifest Transport Envelope回答的正是这个最后一公里问题它定义了一个字节级精确的 HTTP 传输信封契约——endpoint 只能用 HTTPS GET 且不跟随 redirectbody 是未经任何处理的原始 manifest byteskey ID 与 Ed25519 signature 通过两个固定命名的 header 携带transport adapter 只做有限 header 精确 body →UpdateManifestEnvelope的转换绝不参与验签、状态写入、下载或安装。它的目标是把传输库的类型彻底挡在信任判断之外让任何 HTTP client、设置服务或发布脚本都无法各自发明 JSON wrapper、base64 或 redirect 策略从而杜绝待验签 bytes 的歧义。需要特别说明的是本文讨论的 ADR-0022 在当前仓库中属于历史契约状态标注为已被 ADR-0029 取代2026-09-13其后的信任模型经历了 ADR-0025ureq 传输、ADR-0029self_update zipsign再到 ADR-0034detached minisign cargo-packager-updater的多次换实现。但 ADR-0022 确立的设计方法论——字节无歧义、边界清晰、失败关闭、错误码稳定——在今天crates/bongocat-update的实现中依然清晰可见。文章将同时呈现契约原文与演化脉络避免读者把已退役的 header/body 协议误当作现行协议。二、背景离线验签之后还有字节歧义问题ADR-0021 的决策明确了更新信任边界客户端必须先对收到的原始 manifest bytes 执行严格验签成功后才反序列化未知字段、非 v1 schema、超过 1 MiB 或无效 JSON 均拒绝manifest 固定包含 channel、SemVer release、最低可升级版本、单调release_sequence、发布时间与 artifact 列表详见 docs/adr/0021-signed-update-manifest.md。但这套离线验证边界有一个前提缺口验签器拿到的 bytes 必须与发布时签名的 bytes 完全一致。ADR-0022 的背景部分直白地指出了风险让 HTTP client、设置服务或发布脚本各自选择 JSON wrapper、base64 或 redirect 策略会使待验签 bytes 产生歧义也会把传输库类型带入信任判断。这句话拆开看有两个独立问题字节歧义同一个 manifestA 实现用 JSON 字段包一层再 base64B 实现直接透传原始响应C 实现跟随 redirect 后拿到的是 CDN 重写过的内容——验签器无法确定哪个字节序列才是被签名的那一份签名必然时灵时不灵。类型泄漏如果传输层把 HTTP status text、TLS 细节、client 类型、URL 字符串直接暴露给上层上层代码就会开始依赖这些传输细节做判断比如状态码 302 说明有新版本传输库一换信任逻辑就崩。ADR-0022 的解法是把网络响应收敛为一个标准化的信封固定 endpoint 语义、固定 body 语义、固定 header 语义、固定转换边界其余一切验签、状态、调度、下载、安装都在信封之外另行实现。三、核心契约一endpoint 的强制语义ADR-0022 对 manifest endpoint 给出了四条不可协商的约束约束内容目的协议只能经 HTTPSGET获取传输层加密是信任链的地基重定向客户端不跟随 redirect避免最终拿到哪份 bytes由 CDN/中间层决定保证待验签字节无歧义状态码只接受 HTTP200非 200重定向、错误页、代理拦截页一律视为获取失败来源endpoint 自身由不可变环境发布配置提供不能来自用户 config、CLI 或运行时输入把去哪里取更新固化为构建期事实杜绝用户配置污染信任根第四点尤其关键endpoint 不属于用户可配置项。这与 ADR-0021verifier 由不可变构建环境构造的设计一脉相承——如果用户 config 能改 endpoint那么这个 endpoint 是官方发布的这一信任前提就不成立了。该原则在后续演化中也被继承ADR-0025 规定UreqUpdateManifestSource只接受UpdateManifestEndpointendpoint 最多 2 KiB、必须是无 credentials、无 fragment 且具有 host 的 HTTPS URL同样绝不来自用户 config、CLI 或运行时输入ADR-0034 落地为固定的releases/latest/download/latest.json共享 manifest 地址crates/bongocat-update/src/runtime/mod.rs中的RELEASE_MANIFEST_NAME等编译期常量。四、核心契约二body 必须是未经处理的原始 bytesADR-0022 规定响应 body 是不经 JSON 解析、字符转换、解压或重编码的 manifest 原始 bytes最大为 1 MiB。逐条拆解这条约束不 JSON 解析HTTP client 不得把响应按 JSON 读入再序列化输出。任何读-改-写都可能改变字节序列键序、转义、空白而 Ed25519 detached signature 覆盖的是精确的原始字节。不字符转换不按 charset 解码再编码。UTF-8 之外或声明了其他 charset 的内容一律按原始字节看待。不解压即便服务器用 gzip 传输Content-Encoding 或 transparent compression解压后的字节不是网络上的原始字节。这一风险在 ADR-0025 中被再次点名transparent compression 会改变 detached Ed25519 signature 必须覆盖的原始 bytes因此 ADR-0025 在ureq 3.4.0上显式关闭 gzip、charset、cookie 与 proxy feature。不重编码不做任何字节重排。1 MiB 上限与 ADR-0021 的 manifest 大小上限一致防止内存与带宽被异常响应耗尽ADR-0025 进一步给出实现手法——Read::take(1 MiB 1)有界读取超过上限与空 body 均通过既有manifest_too_largeverifier code 失败关闭。从实现角度这条约束的工程含义是transport 层应当把响应 body 视为不透明的字节流原样搬运到信封里任何语义解读都留给验签成功之后的反序列化阶段。这正是传输与信任解耦的直接体现。五、核心契约三两个 header 的精确语法manifest 的签名信息不放在 body 里body 必须是纯粹的原始 manifest bytes而是通过两个固定命名的 HTTP response header 携带Header语法约束语义bongocat-update-key-id最多 64 字节 ASCII只允许字母、数字、-、_和.公钥标识用于在编译期信任公钥集中定位对应公钥ADR-0021 以 key ID channel sequence 有效窗绑定公钥bongocat-update-signature-ed25519恰好 128 个小写十六进制字符64-byte detached Ed25519 signature 的 hex 编码对两个 header 的失败处理是失败关闭fail closed缺失、过长或语法无效的 header一律以稳定的 update error code 失败关闭绝不宽松解析、猜一个默认值继续。注意这里的失败关闭原则——拿不到签名信息就拒绝继续——从 ADR-0022 一路延续到当前实现ADR-0034 规定RELEASE_SIGNING_KEY为None、空串或纯空白时runtime 在发出任何请求之前返回update_signature_key_missing系统菜单不会在没有有效公钥时显示检查更新入口crates/bongocat-update/src/runtime/mod.rs的configured_signing_key门禁与 crates/bongocat-update/src/diagnostics.rs 的SignatureKeyMissing错误码。语法约束的设计动机值得展开key ID 被限制为字母数字 -_.的 ASCII 子集是为了让它可以安全地出现在日志、诊断导出或任何文本通道中而不引入注入风险signature 被固定为恰好 128 个小写 hex而非大小写混用或 base64是为了让字节长度与字符集都可被严格校验——任何偏离都意味着传输被篡改或实现有 bug理应失败而不是被宽容处理。六、核心契约四UpdateManifestEnvelope的职责边界信封转换由transport adapter完成。ADR-0022 用一句话划定了它的全部职责transport adapter 只把有限 header 和精确 body 转为UpdateManifestEnvelope。并且明确列出 adapter不做的事不验证 manifest验签、schema 校验属于 ADR-0021 的 verifier不写入 sequence state防降级状态的提交属于验证成功后的 session 职责不下载 artifact不调用 installer。envelope 只能被交给 ADR-0021 的 verifier/session由后者完成验签、严格 schema 验证与 sequence 推进。同时HTTP、TLS、代理、状态文本和 response 类型不离开 transport adapter。自动/手动调度、取消、下载与安装另行实现。这条信息不出边界原则是整份 ADR 的灵魂传输层可以把连接失败TLS 错误代理不可达非 200 状态翻译成有限的、匿名的错误类别向上传递但绝不把底层的 URL、status text、TLS 细节或 client 类型泄漏给上层——否则上层代码一旦依赖这些细节换传输库就是一次信任链重构。这一原则在 ADR-0025 中具体化为endpoint、status、transport 和 body-read 错误只公开固定匿名 transport code底层 URL、HTTP status text、TLS 或 client 类型不离开 update crate。七、验证策略单元测试锁契约网络测试留后续ADR-0022 的验证段落给出了两阶段的测试策略这也是契约先行工程方法的范例阶段一契约落地时bongocat-update单元测试必须覆盖envelope 的 body 上限1 MiB 边界内/外key ID / signature 编码拒绝非法字符、长度错误、大小写错误exact-byte 保留envelope 内 body 与网络响应 body 逐字节一致通过 envelope 的验签路径把信封交给 verifier 能成功完成验签。阶段二网络 adapter 补上后要求补充真实网络条件下的测试真实 HTTPSredirect确认不跟随代理非-200 响应截断 body超限 body。这个先锁字节语义、再测网络行为的顺序是有意的字节语义是契约的核心可以在无网络环境下用单元测试钉死网络行为依赖具体 adapter 实现属于后续边界。从仓库现状看crates/bongocat-update/tests/release_manifest_capability.rs正是这种离线能力测试思路的延续——它用 loopback HTTP 服务把生产端的签名器cargo_packager::sign::sign_file与应用实际运行的验签器放在一起跑覆盖共享 manifest 的平台键查找、被篡改的载荷、未知密钥签名的载荷、空公钥与 macOS 整包替换不依赖真实网络与真实 GitHub。八、后续边界这份 ADR 刻意不做的决定ADR-0022 在结尾明确列出了一份不决策清单这些决定被推迟给后续 ADR不选择 HTTP crate具体 client 由 ADR-0025 定为ureq 3.4.0不选择 Production endpoint线上地址属于发布基础设施决策不选择公钥注入方式编译期公钥集由 ADR-0021 定义不授权下载、包签名、installer 权限或回滚行为分别属于传输之后、安装之后的独立 contract。这种每份 ADR 只封一段边界的做法让整个更新系统的安全论证可以被逐段审查传输信封0022→ HTTPS transport0025→ 第三方库边界0029→ detached minisign 信任模型0034每一层只承诺自己职责范围内的事情跨层问题在边界处显式声明不属于本 ADR。九、演化与现状从自研信封到第三方库的信任模型变迁ADR-0022 的传输信封契约属于第一代自研更新栈的一部分与 ADR-0021 的 manifest v1 detached Ed25519、ADR-0025 的 ureq 传输共同组成。此后信任模型经历了三次换实现当前仓库的bongocat-update已不再存在UpdateManifestEnvelope与那两个 header——搜索源码仅能在历史 ADR 文档中找到它们。演化轨迹如下阶段ADR信任模型传输方式信封/header 契约第一代ADR-0021 / ADR-0022 / ADR-0025detached Ed25519 清单签名先验签后解析自研固定ureq 3.4.0HTTPS-only、无 redirect、仅 200、禁透明压缩UpdateManifestEnvelopebongocat-update-key-id/bongocat-update-signature-ed25519headerbody 1 MiB 原始字节第二代ADR-0029zipsign 归档内嵌 ed25519 签名self_update 1.3.0的 ureq feature退役manifest v1 schema 与 1 MiB 上限一并废除第三代现行ADR-0034detached minisign 签名BLAKE2b-512 预哈希 8 字节 key IDcargo-packager-updater 0.2.3default-features false仅rustls-tls退役改为一份共享 static 形状 manifest顶层versionos-arch的platforms映射每个条目含url、signature、format换实现的直接原因是能力缺口而非实现缺陷ADR-0029 暴露 zipsign 只能签.zip与.tar.gz裸.exe/.dmg必然验签失败且self_update的 replace-and-verify 语义不适用于 NSIS 系统安装器docs/adr/0034-detached-minisign-update-trust-model.md 对这两条有完整论证。值得注意的是minisign 与 zipsign密码学上不互通预哈希算法与 key ID 语义不同所以换模型等于换信任模型不是换封装。从当前源码看crates/bongocat-update/src/lib.rs第三代实现的职责划分与 ADR-0022 的边界思想一脉相承传输与信任决策由库cargo-packager-updater拥有bongocat-updatecrate 只保留 BongoCat 特有的策略不可变的ReleaseConfigurationrepository、channel、target、ReleaseChannel门禁Development 构建不允许联网安装、匿名UpdateDiagnostics契约验签发生在安装之前Update::download()读完 payload 后立即调用verify_signatureinstall()只接受已验签的字节第三方错误、配置与平台类型全部映射为项目自有类型不扩散为公共 API——diagnostics.rs开头的模块注释明确写着本模块刻意不包含任何cargo_packager_updater类型应用诊断边界ADR-0016 / ADR-0027只能看到稳定的、无路径的错误码与匿名计数器。十、仍然有效的遗产三条穿越三代实现的设计原则尽管 ADR-0022 的 header/body 协议已退役它所确立的方法论在现行实现中依然成立可以直接作为其他项目的契约设计清单待验签字节必须无歧义验签器只能接收签名时的那份字节。无论传输层换成 ureq、self_update 还是 cargo-packager-updater这个前提从未改变——第三代实现中库在验签前把整个 payloadread_to_end进内存正是为了确保验签对象是完整、未改动的载荷。失败关闭而非失败开放ADR-0022 要求缺失/非法 header 以稳定 error code 失败ADR-0034 在RELEASE_SIGNING_KEY缺失时于任何网络请求之前返回update_signature_key_missing。注意第三代还专门补了一道防线库对空 pubkey 本身就会解码失败fail-closed项目仍保留自己的门禁因为要产出的是稳定、无路径的错误码而不是库错误。第三方类型不得离开边界ADR-0022 要求 HTTP/TLS/代理/status text/response 类型不离开 transport adapter今天的 crates/bongocat-update/src/diagnostics.rs 用 14 个稳定错误码UpdateErrorCode::ALL从update_not_configured到update_internal_failed和 10 项匿名计数器封住诊断导出边界sanitized()方法会把任何未被识别的 provider 文本过滤掉——未知错误细节可以丢弃但绝不能原样泄漏。十一、延伸阅读信任边界与验签语义docs/adr/0021-signed-update-manifest.mdHTTPS transport 实现已退役docs/adr/0025-signed-manifest-https-transport.md第三方库边界与替换已退役docs/adr/0029-third-party-update-library-boundary.md现行 detached minisign 信任模型docs/adr/0034-detached-minisign-update-trust-model.md现行实现crates/bongocat-update/src/lib.rs、crates/bongocat-update/src/runtime/mod.rs、crates/bongocat-update/src/diagnostics.rs离线能力测试签名器 × 验签器互操作crates/bongocat-update/tests/release_manifest_capability.rs赞分享桌面应用【免费下载链接】BongoCat BongoCat — A cross-platform interactive desktop pet that brings fun to your desktop!项目地址https://gitcode.com/gh_mirrors/bong/BongoCat点击查看免费下载相关推荐BongoCat 签名更新清单的 HTTPS 传输契约ADR-0025 的端到端安全设计与演进BongoCat 签名更新清单的 HTTPS 传输契约ADR 0025 的端到端安全设计与演进 导读 本文以 BongoCat 更新子系统中的 ADR 002桌面应用IronClaw 扩展契约层解析ironclaw_extension_contracts 的职责边界、模块清单与安全密封设计IronClaw 扩展契约层解析ironclaw_extension_contracts 的职责边界、模块清单与安全密封设计 IronClaw 是一个以隐私、人工智能AI 应用交互助手AI AgentIronClaw 扩展契约层ironclaw_extension_contracts 的词汇、边界与密封设计解析IronClaw 扩展契约层ironclaw_extension_contracts 的词汇、边界与密封设计解析 本文基于 IronClaw一个以隐私、安全人工智能AI 应用交互助手AI Agent上一篇Jupytext 将 Wolfram 语言 Notebook 转换为 Markdown格式、语言标记与 .wolfram 扩展名解析下一篇easy-vibe 实战指南如何判断一个好点子——从用户痛点找到愿意付费的产品方向创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表