隐私与数据处理

本地构建不会发送任何内容。云端构建在内存中完成混淆,不保留任何东西,除了你要求存储的 Protection Map,这项功能可以关闭。遥测默认开启,仅在构建报告错误级别诊断时上报,干净的构建从不上报,并可通过一个环境变量关闭。

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 会在完成混淆的服务器上生成并保留它,因此你可以从控制台打开任意一次最近构建的地图。

你的源代码在此处静态留存的唯一位置

存储 Protection Map 默认按项目开启,已存储的地图可被拥有该项目的工作区的每一位成员读取。如果你的源代码不应在整个工作区内可读,工作区管理员可以在该项目的设置中关闭这项设置。

  • 存储的内容: 每次构建的地图数据——你的原始源代码,加上着色背后按词元计算的指标,压缩并 gzip 后存入 Cloudflare R2,静态加密存储,再加上一行用于控制台的汇总数字。你的混淆输出不会被存储。
  • 作用域限定在一个项目,即该次构建的密钥所绑定的那个项目。
  • 只有该工作区的成员才能读取。 不公开、不被索引,也没有可分享的链接。
  • 保留期:一年,以及每个项目最近 500 次构建,以先到者为准。 一个按小时运行的任务会删除超出任一界限的内容。对于频繁构建的项目,次数上限会先触发。它限制了你的源代码在任一时刻存在多少个副本。
  • 地图可能以部分形式被存储。 当一次构建耗时过长,捕获会在混淆结束之前停止。存储的记录会说明哪些代码块被跳过,以及原因。
  • 关闭它会让该项目的新构建不再存储任何内容。已存储的地图会按上述保留期自然过期,而不会被立即删除。本地构建不受影响:本地构建写入 .afterpack/ 的 Protection Map 永远不会离开你的机器。
  • 关闭后仍会记录的内容: 构建的各项数字(覆盖率、膨胀率、复杂度、耗时),这样项目的控制台图表才能继续正常工作。这些是从构建中得出的聚合数据,不包含任何代码,其中也没有任何内容可以被还原为代码。

分包处理方

一次云端构建会涉及以下处理方。源代码在被混淆期间仅在内存中经过 Cloudflare;Cloudflare 也是唯一会静态持有源代码的一方,即上文所述的 Protection Map:

分包处理方角色
CloudflareWorkers / R2 / D1:边缘计算、路由、Protection Map 存储,以及账户数据库
Creem仅用于账单,作为记录商户;从不接收源代码
Email / auth providers用于账户和密钥生命周期事件的魔法链接与事务性邮件;从不接收源代码
Anthropic(通过 Cloudflare AI Gateway)为站内助手("Ask AfterPack")提供支持;会接收你输入给它的内容,以及它为回答而读取的文档页面,但绝不会接收你的源代码

数据驻留

上面的内容回答了源代码是否被存储的问题。数据驻留是一个独立的问题:请求处理期间数据在哪里被处理,以及已存储的地图存放在哪里。

两者都不会固定在某个区域。云端构建会被 Cloudflare 路由到附近的区域,在故障转移或负载较高时可能落在其他区域。没有按请求固定的区域,R2 存储也不会被锁定在某个区域。如果你需要确定的数据驻留保证,请使用本地构建。 AfterPack 完全运行在你自己的基础设施上,因此不存在数据驻留问题。

DPA 与合规

数据处理协议(DPA)可应要求提供。你签署的 DPA 是具有法律效力、可执行的合同,并指回上文所述的分包处理方名单和数据驻留行为。

下一步

  • 云端 API 参考:这些保证所适用的传输协议。
  • 部署模式:本地与云端的对比,以及各自发送的内容。
  • Protection Map:已存储的地图展示了什么,以及按项目开关的位置。
  • Pro:在云端运行到底能换来什么。
  • 工作区与项目:谁能读取什么,以及密钥的作用域如何界定。
  • 控制台:已存储的地图及其构建记录展示在哪里。