AfterPack 的混淆产品按以下方式处理你的代码和账户数据。本网站的 Cookie 与分析数据在隐私政策中单独说明。
本地(Free)构建从不会将你的源代码发送到任何地方。云端(Pro)构建在内存中完成混淆,并在请求结束时丢弃源代码。有一项产物会被存储:供控制台使用的 Protection Map。它以工作区为作用域、会过期,并且你可以按项目关闭它。遥测默认开启,仅在构建报告错误级别诊断(被拒绝或部分完成的构建)时上报,干净的构建从不上报,并可通过 AFTERPACK_telemetry_enabled=false 关闭。DPA 与完整的分包处理方名单可应要求提供。
本地构建不会发送任何内容
本地构建以原生二进制程序的形式在你的机器上运行 AfterPack。没有任何东西会离开你的文件系统,因此下文的云端部分不适用于它。本地构建唯一发出的网络请求是下文所述的遥测上报,它只在构建报告错误级别诊断(被拒绝或部分完成的构建)时触发,不携带源代码,并且可以关闭。
云端构建在内存中完成混淆,不保留任何东西
当一次 Pro 构建将源代码发送到 api.afterpack.dev 进行混淆时,它仅在内存中处理,仅持续那一次请求的时长,随后即被丢弃:
- 请求运行在一个沙盒化的 Cloudflare Worker 隔离环境中,该环境会在请求边界处被销毁。响应结束后,没有任何东西会留存下来。
- 日志永远不携带源代码。 日志行携带构建 ID、文件数量、字节总数、诊断代码,以及失败文件的路径。它们永远不携带文件内容、标识符名称或常量值。
无论你是直接调用 API、通过设置了 AFTERPACK_key 的 CLI,还是通过框架插件,情况都完全相同。它们都使用云端 API 参考中描述的协议。
有一项产物会被存储:下文所述的 Protection Map,它在混淆完成后写入。你上传用于混淆的源代码,在请求结束时依然会被清除。
日志记录什么,不记录什么
| 已记录 | 从不记录 |
|---|---|
| 时间戳(收到请求、响应关闭) | 文件内容 |
| HTTP 状态码 | 标识符名称 |
| 构建 ID、文件数量、输入/输出字节总数 | 常量值,包括恰好出现在源代码中的密钥 |
诊断代码(DIAG_*) | 遥测中的诊断消息文本 |
| 客户端 IP,用于限流 | Source map 的 sources / sourcesContent |
| 工作区层级,用于计量 | 任何可能暴露你业务逻辑的内容 |
聚合指标(每日请求数、按工作区计量的字节数、构建耗时)以计数器形式保留,不包含任何代码。
遥测默认开启,仅报告构建的错误级别诊断
客户端可以上报匿名的构建诊断信息,以便发现并修复引擎缺陷。除非你关闭它,否则它默认开启。一次干净的构建没有什么可报告的:
- 只有发出
error或critical诊断的构建才会发送任何内容。 一次干净的构建什么都不会发送:没有周期性心跳,没有阶段耗时,也没有一次正常构建的使用统计。 - 通过
AFTERPACK_telemetry_enabled=false关闭它,在 CLI 上使用--telemetry.enabled=false,或在你的集成配置中使用telemetry: { enabled: false }。这就是全部的开关。 - 它在 CI 中的行为完全相同。 没有任何 TTY 或 CI 检测会改变默认值或跳过上报;负载只是记录
ci: true,读取自你的流水线本就设置的同一个CI变量。 - 绝不询问。 安装后的第一次构建会打印一条一次性提示(收集了什么、没有收集什么、如何关闭),然后继续执行。它从不会阻塞等待回答。状态(一个每 30 天轮换一次的随机安装 ID,以及该提示是否已打印过)保存在
~/.afterpack/telemetry.json中。 - 测试运行豁免。
NODE_ENV=test和 Vitest 自身的VITEST标记会禁用遥测。
当构建报告错误级别诊断时,会收集什么
- 失败诊断的代码、严重级别和字节偏移范围,加上按诊断类型选取的一小组带类型字段,但绝不包含其自由文本消息
- 引擎、客户端和 Node 的版本、操作系统/架构,以及检测到的框架
- 构建是否运行在 CI 中
- 复杂度级别:一个具名的预设,或者在使用原始
complexity时为custom - 文件数量和构建耗时,以分档(
5-20、1-5s)而非精确数字呈现;精确数字会成为某个项目的指纹 - 一个每 30 天轮换一次的随机安装 ID,绝不从你的机器或项目派生
无论是否遥测,都绝不收集的内容
- 源代码或文件内容
- 遥测中的文件名和文件路径。如上所述,云端构建的服务器端日志会携带一个路径,即批次中失败的那个文件
- 诊断的消息文本,永远不会;只有其稳定的
code - API 密钥或凭据
- 常量值
- 字符串编码方式的选择
- 除你账户本身持有的信息之外,任何能识别用户身份的信息
遥测的结构是固定的。
云端构建的 Protection Map 会被存储,你可以关闭它
Protection Map 就是你的原始源代码,按其中每个词元经历了多少变换着色。在云端构建中,AfterPack 会在完成混淆的服务器上生成并保留它,因此你可以从控制台打开任意一次最近构建的地图。
- 存储的内容: 每次构建的地图数据——你的原始源代码,加上着色背后按词元计算的指标,压缩并 gzip 后存入 Cloudflare R2,静态加密存储,再加上一行用于控制台的汇总数字。你的混淆输出不会被存储。
- 作用域限定在一个项目,即该次构建的密钥所绑定的那个项目。
- 只有该工作区的成员才能读取。 不公开、不被索引,也没有可分享的链接。
- 保留期:一年,以及每个项目最近 500 次构建,以先到者为准。 一个按小时运行的任务会删除超出任一界限的内容。对于频繁构建的项目,次数上限会先触发。它限制了你的源代码在任一时刻存在多少个副本。
- 地图可能以部分形式被存储。 当一次构建耗时过长,捕获会在混淆结束之前停止。存储的记录会说明哪些代码块被跳过,以及原因。
- 关闭它会让该项目的新构建不再存储任何内容。已存储的地图会按上述保留期自然过期,而不会被立即删除。本地构建不受影响:本地构建写入
.afterpack/的 Protection Map 永远不会离开你的机器。 - 关闭后仍会记录的内容: 构建的各项数字(覆盖率、膨胀率、复杂度、耗时),这样项目的控制台图表才能继续正常工作。这些是从构建中得出的聚合数据,不包含任何代码,其中也没有任何内容可以被还原为代码。
分包处理方
一次云端构建会涉及以下处理方。源代码在被混淆期间仅在内存中经过 Cloudflare;Cloudflare 也是唯一会静态持有源代码的一方,即上文所述的 Protection Map:
| 分包处理方 | 角色 |
|---|---|
| Cloudflare | Workers / R2 / D1:边缘计算、路由、Protection Map 存储,以及账户数据库 |
| Creem | 仅用于账单,作为记录商户;从不接收源代码 |
| Email / auth providers | 用于账户和密钥生命周期事件的魔法链接与事务性邮件;从不接收源代码 |
| Anthropic(通过 Cloudflare AI Gateway) | 为站内助手("Ask AfterPack")提供支持;会接收你输入给它的内容,以及它为回答而读取的文档页面,但绝不会接收你的源代码 |
数据驻留
上面的内容回答了源代码是否被存储的问题。数据驻留是一个独立的问题:请求处理期间数据在哪里被处理,以及已存储的地图存放在哪里。
两者都不会固定在某个区域。云端构建会被 Cloudflare 路由到附近的区域,在故障转移或负载较高时可能落在其他区域。没有按请求固定的区域,R2 存储也不会被锁定在某个区域。如果你需要确定的数据驻留保证,请使用本地构建。 AfterPack 完全运行在你自己的基础设施上,因此不存在数据驻留问题。
DPA 与合规
数据处理协议(DPA)可应要求提供。你签署的 DPA 是具有法律效力、可执行的合同,并指回上文所述的分包处理方名单和数据驻留行为。