news 2026/9/18 9:14:05

OpenDesign 隐私与遥测架构解析:本地优先、双层遥测与可审计的数据脱敏实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenDesign 隐私与遥测架构解析:本地优先、双层遥测与可审计的数据脱敏实现

OpenDesign 隐私与遥测架构解析:本地优先、双层遥测与可审计的数据脱敏实现

【免费下载链接】open-design🎨 Best DeepSeek Harness Design Plugin. The open-source Claude Design alternative. 🖥️ Local-first desktop app. 🖼️ Your coding agent becomes the design engine: prototypes, landing pages, dashboards, slides, images & video — real files, HTML/PDF/PPTX/MP4 export. 🤖 Claude Code / Codex / Cursor / DeepSeek Harness / OpenCode & 20+ CLIs via BYOK.项目地址: https://gitcode.com/gh_mirrors/opend/open-design

OpenDesign 是一款本地优先(local-first)的开源设计工作台,其桌面端与 Web 端围绕"数据留在本机"的原则构建了完整的隐私体系。本文以仓库根目录的 PRIVACY.md 为纲领,结合apps/web/src/analyticsapps/daemon/src中的真实源码与路由实现,系统讲解 OpenDesign 的两类遥测(产品分析 vs 安全可靠性)、收集范围与豁免清单、脱敏机制(会话回放掩码、before_send清洗钩子)、传输链路(PostHog / Langfuse / 遥测中继)、匿名 ID 生命周期、数据删除语义以及 BYOK 密钥的处理方式。读完本文,你将能清晰回答"OpenDesign 到底收集什么、为什么收、如何脱敏、如何关闭、如何删除",并能在源码层面逐行验证每一个隐私承诺。

一、设计总纲:本地优先 + 两类遥测

OpenDesign 的隐私模型建立在一个明确的产品事实上:项目、生成文件与 BYOK API 密钥全部保存在用户本机。即使遥测服务完全不可达,本地项目与文件工作流依旧可用;只有依赖模型的服务才需要运行时或你所选择的服务提供商在线。这一承诺在 PRIVACY.md 中作为开篇声明,也是理解整套遥测架构的前提——遥测只是"锦上添花"的质量信号,而非产品运行的必需依赖。

在此基础上,OpenDesign 将遥测明确划分为两个类别:

类别默认状态可否关闭用途
产品分析与质量追踪(Product analytics & quality traces)默认开启可在Settings → Privacy关闭或收窄产品使用统计、运行质量评估
安全与可靠性遥测(Safety & reliability telemetry)在配置了遥测目标(telemetry destination)的构建中始终开启不可由通用分析开关关闭崩溃、启动失败、流中断等产品健康诊断

两类遥测在源码中是物理分离的两条通道:产品分析通道受用户同意开关控制(telemetry.metrics/telemetry.content),而安全可靠性通道在 apps/daemon/src/analytics.ts 中通过captureSafety接口刻意跳过同意检查——该文件的注释明确指出:"safety/reliability events … intentionally BYPASS the user's analytics consent toggle. The product policy is: we always retain ground-truth stability data even for opted-out users",并要求产品侧在Settings → Privacy的文案中如实说明这一例外。

对于 Fork 与开发构建,由于没有遥测目的地凭据(如POSTHOG_KEY),两类遥测都不会发送。这一点在源码中有双重保证:daemon 侧 createAnalyticsService 在POSTHOG_KEY未设置时直接返回NOOP_SERVICE(所有入口均为 no-op);web 侧 getAnalyticsClient 在/api/analytics/config返回enabled:false, key:null时返回null,且不会加载posthog-js

二、产品分析默认开启:首启横幅与双重开关

产品使用遥测默认开启opt-out模式)。首次运行时,应用会展示隐私披露横幅,在你执行任何其他操作之前明确告知收集范围,并要求你在ShareDon't share之间做出选择。选择 Share 保持产品分析开启;选择 Don't share 则关闭所有可选通道。此后你可以随时通过Settings → Privacy改变决定。

在源码层面,这一"默认开启"的语义落在 daemon 的应用配置中。查看 apps/daemon/src/app-config.ts 可以看到:当保存的配置中完全没有telemetry字段(全新安装、披露前状态)时,程序会填充默认值telemetry: { metrics: true, content: true }——即两个可选通道默认均为开启。daemon 的analytics.ts在每次捕获时还会防御性地二次核验这一配置(if (appCfg.telemetry?.metrics !== true) return),即使未来某个请求错误携带了分析头,daemon 也会在捕获前丢弃事件(apps/daemon/src/analytics.ts)。

Settings → Privacy中对应两个可选控制项:

  • Anonymous metrics(匿名指标)——运行次数、Token 用量、错误率、耗时,以及产品交互事件、页面跳转、Web 性能与隐私掩码会话回放。
  • Conversation and tool content(对话与工具内容)——用于质量评审的提示词、助手回复、工具输入/输出、prompt 栈上下文与附件/产物清单元数据;内容会被截断并清洗,已知携带产物内容的工具载荷会被替换为脱敏标记(redaction markers)。该通道要求"指标"与"内容"两个开关同时开启才会生效。

这一双开关门控在 Langfuse 追踪模块中有明确实现:查看 apps/daemon/src/langfuse-trace.ts,其头注释写道 "Privacy gates are layered:prefs.metricsis the master switch, andprefs.contentis required for Langfuse traces because this sink is used for turn-quality evals. If either is off, no network call is made."——即 Langfuse 作为质量评估 sink,只有在两个开关同时打开时才会收到数据。

前端的开关即时生效:web 端 AnalyticsProvider 暴露setConsent(granted)App.tsx通过useEffect监听config.telemetry?.metrics,用户切换开关后立即调用applyConsent,无需等待下一次刷新。对应实现见 apps/web/src/analytics/client.ts:关闭时调用posthog.opt_out_capturing()posthog.reset(),前者是全局闸门——不仅停止显式capture(),还同时停止 autocapture、$pageview$pageleave$exception、web vitals 与 dead clicks;后者清除 localStorage 中持久化的ph_*_posthog条目,防止旧的distinct_id在后续操作中被重新拼接。

三、收集什么:匿名指标、会话内容与安全诊断

3.1 匿名指标通道

当可选共享开启时,应用可能向 Open Design 团队发送:

  • 匿名指标:run 计数、token 用量、错误率、耗时;产品交互事件、页面跳转、Web 性能数据,以及隐私掩码的会话回放(privacy-masked session replay)
  • 回放的掩码策略在 apps/web/src/analytics/client.ts 中由三层规则构成,按覆盖面从大到小:
    1. maskTextSelector: '*'——将所有文本节点掩码为星号,提示词、生成产物文本、模型名、项目标题等任何未来新增的文本面都被自动覆盖;
    2. maskAllInputs: true——掩码所有<input>/<textarea>的值,提示词输入框与 BYOK 密钥字段都被抹空;
    3. blockSelector: 'iframe'——完全屏蔽所有内嵌 iframe,产物预览的 FileViewer iframe 与插件内嵌渲染的 HTML 以惰性占位符呈现,recordCrossOriginIframes: false作为额外保险。

因此,提示词、密钥、项目文本与生成的预览不会作为可读屏幕内容被记录

3.2 对话与工具内容通道

该通道包含你的提示词、助手回复、工具输入、工具输出、prompt 栈上下文,以及质量评审所需的附件/产物清单元数据。内容在发送前会截断与清洗

  • 单条输入上限INPUT_MAX_BYTES = 64 * 1024,输出上限同为 64KB,工具输入/输出各8 * 1024字节,单批硬上限HARD_BATCH_MAX_BYTES = 1024 * 1024(见 apps/daemon/src/langfuse-trace.ts);
  • 已知携带产物内容的工具载荷会被替换为脱敏标记;
  • 该通道同时要求 metrics 与 content 两个开关开启(见上文 3.2 的双开关门控)。

3.3 独立于开关之外:安全与可靠性遥测

无论上述开关状态如何,配置了遥测目标的构建仍可能发送有界、已清洗的诊断信息,覆盖:浏览器/daemon 异常、白屏、长任务、资源或 SSE 失败、卡死 run、生命周期失败,以及 daemon 启动前就崩溃的打包应用。典型字段包括:产品版本/渠道、OS/运行时事实、失败阶段、错误类型/消息/堆栈、耗时。

安全通道的实现细节值得关注:

  • daemon 侧captureSafety在无installationId时使用合成匿名 ID(daemon-anon-<时间戳>-<随机串>,见 apps/daemon/src/analytics.ts);致命退出路径会先await captureSafety再调用shutdown(),确保崩溃事件进入 posthog-node 本地缓冲后才 flush(同一文件 apps/daemon/src/analytics.ts)。
  • 路由侧/api/observability/event端点(请求体限制 64kb)直接调用captureSafety,用于浏览器/daemon 异常上报(apps/daemon/src/routes/telemetry.ts)。
  • 致命处理器installFatalTelemetryHandlers监听uncaughtException/unhandledRejection,在 1 秒超时内尽力 flush 后退出(apps/daemon/src/routes/telemetry.ts)。

清洗保证:主目录路径、URL 查询字符串、输入文本等已知敏感字段在发送前被清除。$exception事件中的绝对文件系统路径会被重写为app://前缀的相对路径(如/Applications/Open Design.app/Contents/Resources/...app://apps/web/src/foo.tsx),实现见 apps/web/src/analytics/scrub.ts。安全上报是 best-effort 的,永远不会阻塞核心工作流或失败进程的退出

四、绝不收集什么:不可逾越的底线

PRIVACY.md 明确列出四类绝对不收集的数据,每一类都能在源码中找到对应的工程保障:

  1. 生成产物文件的内容——会话回放的blockSelector: 'iframe'阻止了产物预览 iframe 的 DOM 被序列化;Langfuse 追踪中"已知携带产物内容的工具载荷"会被替换为脱敏标记。
  2. BYOK API 密钥、认证 Token 与其他存储凭据——密钥仅存储在本地并被本地 app/daemon 使用(见 apps/daemon/src/analytics.ts 对应章节),不作为遥测字段发送;scrub.tsinput/textarea$el_textattr__valueattr__placeholderattr__aria_label一律清除(apps/web/src/analytics/scrub.ts)。
  3. 隐私掩码会话回放中的可读提示词、项目或产物文本——maskTextSelector: '*'将每个文本节点掩码为星号。
  4. 内容开关关闭时的对话/工具内容——双开关门控保证任何单一通道都无法单独触发内容上报。

关于 IP 地址需要特别澄清:遥测事件载荷有意不包含源 IP 字段,自由文本内容的清洗规则也会移除 IP 地址模式;但作为任何 HTTPS 请求,接收方网络服务天然能看到连接来源 IP,配置的 PostHog 服务可能将其用于国家/地区等地理信息增强。PRIVACY.md 明确指出:"不要将'anonymous'理解为'传输层无法观察到 IP 地址'"。

五、传输链路:PostHog、Langfuse 与遥测中继

产品事件、掩码回放与安全/可靠性事件通过配置的PostHogingestion 端点发送;浏览器安全事件可能直接走 PostHog 的公开 ingestion API,确保常规分析客户端加载之前发生的错误不丢失。当 metrics 与 content 共享同时开启时,详细的 run 质量追踪通过 OpenDesign 遥测中继(telemetry relay)发送到Langfuse;维护者的 smoke-test 配置也可直接使用 Langfuse 凭据。公开的客户端/中继配置不会暴露团队的私有写入凭据

源码中的传输细节:

  • 默认 host:daemon 侧DEFAULT_HOST = 'https://us.i.posthog.com'POSTHOG_HOST可覆盖(apps/daemon/src/analytics.ts);Langfuse 默认https://us.cloud.langfuse.com(apps/daemon/src/langfuse-trace.ts)。
  • 环境变量门控POSTHOG_KEY(可选POSTHOG_HOST)、OPEN_DESIGN_TELEMETRY_RELAY_URLLANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY。任一缺失即整体降级为 no-op——这是"Fork 与开发构建不发遥测"的工程根基。
  • 双端身份统一:web 端通过x-od-analytics-*HTTP 头(device_idsession_idclient_typelocalerequest_id等)把身份传递给 daemon,daemon 用同一device_id作为 PostHogdistinct_id,使双端事件落在同一 person 记录上(apps/daemon/src/analytics.ts)。
  • 去重键:web 与 daemon 对同一事件使用相同的$insert_id,服务端据此合并重复计数(apps/web/src/analytics/client.ts)。
  • 最佳努力原则:所有传输都是 best-effort,分析服务不可用不会把遥测失败变成产品失败——web 端所有 capture 入口都是 fire-and-forget 且吞掉异常,daemon 端client.on?.('error', () => undefined)抑制库内部错误噪音。

六、匿名 ID:随机、不透明、可旋转

对可选分析,应用生成一个随机、不透明的安装 ID(installationId),用于聚合相关事件;它由你的姓名或邮箱派生。安全/可靠性路径在可用时使用匿名安装/设备标识,早期启动失败时可能使用合成的进程/命名空间标识(daemon-anon-*)。

实现要点:

  • daemon 首次需要时会生成 UUID 并写入 app-config(apps/daemon/src/routes/telemetry.ts),installationId字段定义见 apps/daemon/src/app-config.ts;
  • /api/analytics/config仅在用户同意后返回installationId(apps/daemon/src/routes/telemetry.ts);
  • web 端将installationId作为 PostHogbootstrap.distinctID,优先于本地生成的 UUID(apps/web/src/analytics/client.ts),这样 daemon 端捕获与 web 端捕获落到同一 person 记录;
  • 切换开关会执行reset()清空旧身份;applyIdentity在 ID 轮换时先reset()identify()新 ID,确保新会话与已删除的旧身份完全解耦(apps/web/src/analytics/client.ts)。

七、删除你的数据:旋转、停用与保留策略

Settings → Privacy → Delete my data执行三项操作:

  1. 轮换本地匿名 ID——daemon 重新生成installationId,web 端applyIdentity将 PostHog 身份切换到新 ID;
  2. 禁用可选 metrics/content 通道——等价于关闭两个开关;
  3. 不影响:不关闭安全/可靠性例外通道、不召回已收到的事件、不同步抹除处理方的历史记录。已接收的遥测数据按适用保留策略自然老化(age out)。

语义上的精确边界值得强调:删除操作是"去关联(de-identification)+ 停止采集",而非"服务端即时擦除"。这与业界对本地匿名 ID 无法远程撤回的普遍认知一致。

八、BYOK:密钥留在本机

你为编码 Agent 与模型提供商配置的 API 密钥存储在本机,由本地 app/daemon 调用所选提供商时使用。它们不是遥测字段,也绝不会发送给 Open Design 团队。工程保障来自两方面:其一,密钥仅存在于本地配置与 daemon 进程中,遥测载荷的字段清单(如 MCP 分析属性白名单 apps/daemon/src/routes/telemetry.ts)中不存在任何密钥字段;其二,即使密钥曾出现在 DOM 中(如输入框),scrub.tsmaskAllInputs也会在事件与回放中将其抹除。

九、OpenDesign AMR:第一方产品族内的共享

"OpenDesign AMR" 是 OpenDesign 官方的第一方模型服务。由于两者属于同一团队运营的同一产品族,为提供、连接与改进组合体验,双方可能按需共享信息——例如识别你来自 Open Design、帮助你完成初始设置、保持产品协同工作。这种共享发生在自有产品之间,而非与无关第三方;涉及的数据仍遵循本文所述的各项控制。在客户端代码中可看到对应的联合键:AMR 登录后的user_id作为唯一跨项目连接键注册到 PostHog(apps/web/src/analytics/client.ts),退出登录时注销该参数,避免事件携带过期账户 ID。

十、文档与实现同步变更,如何自行审计

PRIVACY.md 声明该文档跟踪已发布应用的数据处理行为,遥测行为变化时页面同步更新。这也意味着仓库本身就是一份可审计的隐私实现清单,建议的验证路径:

  1. 同意门控:apps/daemon/src/app-config.ts(telemetry.metrics/telemetry.content默认值与持久化)→ apps/daemon/src/analytics.ts(捕获前二次核验、captureSafety例外)→ apps/web/src/analytics/provider.tsx(setConsent/setIdentity即时生效)。
  2. 脱敏单点:apps/web/src/analytics/scrub.ts(before_send单一审查点:元素链清洗、URL 清洗、堆栈路径重写)与 apps/web/src/analytics/client.ts(会话回放三层掩码)。
  3. 传输与门控:apps/daemon/src/langfuse-trace.ts(Langfuse 批次构建、字节上限、双开关门控)与 apps/daemon/src/routes/telemetry.ts(/api/analytics/config/api/observability/event、致命处理器、MCP 分析属性白名单校验)。

通过对照 PRIVACY.md 与上述文件,你可以独立验证每一个隐私声明在实现层面的落点——这正是本地优先、可审计的遥测设计对开发者最直接的价值。

结语

OpenDesign 的隐私体系可以概括为三个关键词:本地优先(数据默认留在本机,遥测仅作质量信号)、双层分离(可关闭的产品分析 vs 不可关闭但严格脱敏的安全诊断)、可审计的实现(单一清洗审查点、双开关门控、环境变量门控与匿名 ID 旋转机制全部暴露在开源仓库中)。对使用者而言,掌握Settings → Privacy中的两个开关、首启横幅的 Share/Don't share 选择与 Delete my data 的语义边界,即可完整控制自己的数据流向;对开发者而言,这条从配置、路由到捕获的调用链本身就是一份高质量的隐私工程参考实现。

【免费下载链接】open-design🎨 Best DeepSeek Harness Design Plugin. The open-source Claude Design alternative. 🖥️ Local-first desktop app. 🖼️ Your coding agent becomes the design engine: prototypes, landing pages, dashboards, slides, images & video — real files, HTML/PDF/PPTX/MP4 export. 🤖 Claude Code / Codex / Cursor / DeepSeek Harness / OpenCode & 20+ CLIs via BYOK.项目地址: https://gitcode.com/gh_mirrors/opend/open-design

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 9:10:49

深入llvm-project:理解LLVM IR、构建与Pass开发

如果你是在搜索引擎里敲下“llvm-project”这个词才点进来的&#xff0c;我猜你大概率正面临三种情况之一&#xff1a;要么是编译某个开源项目时看到一长串 LLVM 依赖手足无措&#xff0c;要么是在 glxinfo 输出里看到llvmpipe (LLVM 15.0.7, 256 bits)这样的字符串想知道它到底…

作者头像 李华
网站建设 2026/9/18 9:10:35

Python下划线命名规则:_、__与__xx__的语义契约

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 9:09:48

Linux离线安装SVN实践:基于本地yum源的完整配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 9:09:08

专科生论文降AI率实战:9款工具实测与避坑指南

第一次看到检测报告上“AI疑似率38%”的时候&#xff0c;我整个人是懵的。那篇实训报告是我熬了三个晚上、一句一句敲出来的&#xff0c;从排错日志到设备参数都有据可查&#xff0c;结果系统直接给我标了一堆红。后来跟专业课老师聊完&#xff0c;又拿自己手头的稿子反复试了七…

作者头像 李华
网站建设 2026/9/18 9:09:00

Linux下统计文件个数的正确姿势:find/ls/wc实战详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华