2
0

给 Electron preload 扩能力前,我会先写一份可审计能力清单

最近给一个 Electron 桌面端 AI 工作台补本地能力时,我又碰到一个老问题:Web 页面只想读取配置、选择目录、触发后台任务,preload 脚本却很容易被一点点塞成万能工具箱。短期调用顺手,后面接多窗口、插件面板和自动化任务时,谁能调用什么、参数从哪里来、失败后怎么追踪,就会变成口头约定。

Electron preload 能力清单从 renderer 意图到主进程校验的流程图

原创示意图:renderer 意图先进入类型化 preload API,再经过 IPC 白名单、主进程校验和审计记录,最后触发本地能力。 来源:Codex image generation

问题背景

Electron 的 context isolation 文档说明,preload 脚本和页面运行在隔离上下文里,这个设置从 Electron 12 起默认开启,也是官方推荐的安全设置。官方建议用 contextBridge 把受控 API 暴露给页面,让页面只拿到明确设计过的入口。

这件事在 AI 工作台里很敏感。页面会展示会话、RAG 索引、自动化任务和本地文件入口。能力边界如果只靠函数名约束,很快会出现三类问题:renderer 能发送任意 IPC channel,参数结构到主进程才失败,不同窗口拿到一样的本地权限。

关键难点

第一个难点是 preload API 容易变成透明转发层。Electron 的 context isolation 文档提醒,直接暴露 ipcRenderer.send 这种强 API 是不安全的,正确做法是为每个 IPC 消息提供一个单独方法。contextBridge 文档也提到,完整传递 ipcRenderer 会让代码能发送任意消息,是安全陷阱。

第二个难点是跨进程数据有明确边界。ipcRenderer 文档说明,sendinvoke 的参数会按 Structured Clone Algorithm 序列化,原型链不会被包含,函数、Symbol、WeakMap 等类型会抛异常,DOM 对象和部分特殊对象也不能传到主进程。这个边界如果不提前写进类型和校验,错误会滞后到运行时。

解决思路

我现在会先写一份 preload 能力清单,再由清单生成暴露给 renderer 的 API。每个能力包含 keychannel、调用方式、参数 schema、返回 schema、允许窗口、风险等级和审计开关。renderer 只能看到清单生成后的方法名,preload 负责参数校验和受控转发,主进程再次校验窗口来源和业务权限。

TypeScript 类型也跟着清单走。页面侧拿到 window.coriander.desktop.pickFolder() 这种具体方法,方法返回稳定的 Promise 类型。preload 内部映射到 ipcRenderer.invoke('desktop:pick-folder', payload),主进程只注册清单里存在的 channel。能力新增会变成一次显式评审,评审点自然落在参数、窗口范围和风险等级上。

关键步骤

第一步是按窗口拆能力。知识库页可以读取导入任务状态,却不能直接打开任意本地路径;设置页可以写配置,却不能触发批量文件整理;自动化页可以请求执行任务,但高风险动作要进入确认队列。能力清单里写清 allowedWindows,主进程处理 IPC 时再对窗口标识做校验。

第二步是把参数校验放在两端。preload 先用 schema 拦住明显错误,减少无效 IPC;主进程再做最终确认。跨进程边界只传普通对象、字符串、数字、布尔值和数组,文件句柄、DOM 对象、函数回调都改成受控 ID 或单独流程。

第三步是处理事件订阅。安全文档提醒,直接把 ipcRenderer.on 或原始事件对象传给页面会扩大暴露面。我的做法是只给页面一个窄回调,比如 onTaskProgress(callback),preload 内部丢弃 _event,只把整理后的进度对象交给页面,并返回取消订阅函数。

第四步是写审计记录。每次高风险能力调用都记录 capability key、窗口、参数摘要、调用结果和耗时。日志里不放完整敏感参数,只放可复盘的摘要和 requestId。后面用户问“刚才 AI 为什么改了本地配置”,可以沿着 requestId 查到页面动作、preload 能力、主进程处理和最终结果。

可复用经验

preload 脚本的价值是把 Web 页面和原生能力之间的边界固定下来。能力清单越早出现,Electron 项目越容易从单窗口工具演进到多窗口工作台、插件面板和自动化执行器。凡是会触碰文件、系统配置、外部进程或长期任务的入口,都应该先进入能力清单,再进入代码。

等项目接入 Agent 或 RAG 自动化后,AI 也只能请求清单里的受控能力。桌面端边界清楚,前端类型、IPC 注册、测试样例和审计日志就能沿着同一份清单继续生成。

主要来源

Electron contextBridge

Electron Context Isolation

Electron ipcRenderer

Electron Security

评论