gbrain Publish Skill 实战指南:零 LLM 调用的脑页安全分享与 AES-256-GCM 客户端加密发布
2026/9/20 13:10:40 网站建设 项目流程

gbrain Publish Skill 实战指南:零 LLM 调用的脑页安全分享与 AES-256-GCM 客户端加密发布

【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain

gbrain 的publish技能(位于 plugin/skills/publish/SKILL.md)用于把大脑(brain)中的 Markdown 页面一键转换成精美、自包含的 HTML 文档对外分享,可选客户端 AES-256-GCM 密码加密,全程零服务器依赖、零 LLM 调用。读完本文,你将掌握gbrain publish的完整命令用法、内置的隐私脱敏规则、四种分享工作流,以及底层加密与 HTML 生成的源码级实现原理,可直接把交易备忘录、人物简报、尽调分析等脑内内容安全地送出脑库。

技能定位:Thin Harness, Fat Skills

publish是一个code + skill 配对的组合:

  • 确定性代码gbrain publish负责真正的工作——脱敏、加密、生成 HTML,逻辑全部固化在 src/commands/publish.ts 中,不产生任何 LLM 调用,因此输出可复现、无随机性、零 Token 成本;
  • 技能本身(SKILL.md)只负责"何时用、怎么用"的策略判断,通过 frontmatter 中的triggers自动响应"share this page""publish page""create shareable link"等自然语言指令,并声明依赖get_pagesearch两个工具、mutating: false(发布动作不修改脑库)。

这种"薄编排、厚代码"的设计理念意味着:Agent 只需识别意图,复杂的脱敏与加密逻辑交给经过测试验证的确定性代码,避免每次分享时由 LLM 临场发挥带来隐私泄露风险。

何时触发发布

技能明确的触发场景包括:

  • 用户请求分享某个脑页、生成可分享链接,或直接说 "give me a page";
  • 需要把交易备忘录(deal memo)、人物简报(person briefing)、研究报告发给外部人员;
  • 需要发布尽调分析(data room analysis)或行程计划(trip plan);
  • 任何"脑内容需要离开脑库,但不能暴露整个系统"的场合。

核心判断标准只有一个:内容要离开脑库。凡是输出给外部、且不希望携带内部元数据的场景,都应该走publish通道而不是手工复制 Markdown。

铁律:默认永远加密

SKILL.md将"默认加密"列为契约与反模式双重强调项:

Brain content is private. Default to password-protected unless the user explicitly says "open", "no password", or "public".

  • 用户未指定密码时,自动生成一个随机密码;
  • 密码与分享链接必须走不同渠道传达(如链接发邮件、密码发短信),避免同信道泄露;
  • 只有用户明确说出 "open"、"no password"、"public" 才允许输出明文 HTML。

快速参考:核心命令

以下命令均来自SKILL.md的 Quick Reference,且与 src/commands/publish.ts 中runPublish的参数解析逻辑一一对应:

# 基础发布(输出本地 HTML 文件,不加密) gbrain publish brain/companies/acme.md # 密码保护(自动生成密码) gbrain publish brain/companies/acme.md --password # 密码保护(指定密码) gbrain publish brain/companies/acme.md --password "secret123" # 自定义标题 gbrain publish brain/companies/acme.md --password --title "Acme -- Deal Analysis" # 自定义输出路径 gbrain publish brain/companies/acme.md --out /tmp/acme-share.html

参数行为说明(源自runPublish源码解析逻辑 src/commands/publish.ts):

参数含义默认值
<page-path>输入脑页 Markdown 路径(首个非--开头的参数)必填
--password启用加密;后接非--参数时作为指定密码未指定时自动生成 16 位随机密码
--title "..."覆盖 HTML 标题缺省时取 Markdown 第一个 H1(extractTitle)
--out <path>输出文件路径<输入文件名>.htmlbasename(inputPath, '.md') + '.html'

注意:--out目录不存在时会通过mkdirSync(dirname(outPath), { recursive: true })自动递归创建;缺少输入参数时命令会打印完整 Usage 并以退出码 1 结束。

发布时剥离什么:隐私脱敏白名单

SKILL.md给出的脱敏清单,在源码中由makeShareable()函数逐条实现(src/commands/publish.ts):

剥离项示例原因对应实现正则
YAML frontmattertitle:type:tags:内部元数据^---[\s\S]*?---\n*
[Source: ...]引用所有格式来源溯源属内部信息\s*\[Source:[^\]]*\]
确认编号ABC123DEF→ "on file"PII/预订数据\*\*Confirmation:\*\*\s*[A-Z0-9]{6,}等三种格式
脑内交叉链接JaneJane内部路径\[([^\]]+)\]\(\.[^)]*\/[^)]+\)(保留显示文本)
Timeline 章节---## Timeline之下的全部内容原始证据日志\n---\n\n## Timeline[\s\S]*$
"See also" 行内部引用导航脑库导航信息^-?\s*See also:.*$(多行模式)

保留项:外部 URL(https://...,形如https://example.com的链接不受影响)以及其他所有正文内容。处理结束后还会把连续 3 行以上的空行折叠为最多 2 行(\n{3,}\n\n),并trim()掉首尾空白。

以上每一条脱敏规则都有对应的测试用例背书,见 test/publish.test.ts:例如strips YAML frontmatter验证title: Secrettype: person被移除、Jane is CTO [Source: Crustdata enrichment, 2026-04-01] of Acme.被净化成Jane is CTO of Acme.Works with Jane Doe at Acme.变成Works with Jane Doe at Acme.,同时preserves external URLs确认https://example.com/blog被完整保留。测试还覆盖了.raw/相对链接(脑内原始数据目录)的剥离与空输入、纯 frontmatter 输入等边界情况。

四种分享工作流

方案 A:本地文件(最简)

gbrain publish brain/people/jane-doe.md --password --out ~/Desktop/jane-briefing.html

生成单文件 HTML 后通过邮件、Slack、Airdrop 分享,密码另行单独发送。这是最直接、无任何外部依赖的路径。

方案 B:上传云存储(Supabase Storage)

# 先本地发布 gbrain publish brain/companies/acme.md --password "secret" --out /tmp/acme.html # 上传到 Supabase Storage gbrain files upload /tmp/acme.html --page shares/acme # 获取签名 URL(1 小时过期) gbrain files signed-url shares/acme/acme.html

gbrain files uploadgbrain files signed-url由 src/commands/files.ts 实现:upload子命令(src/commands/files.ts 的分发入口,实现于 uploadFile)会先校验存储后端存在(requireStorageBackend('upload')),再按内容哈希去重(已上传且哈希一致时提示File already uploaded (hash match)),最后调用storage.upload写入对象;signed-url子命令(signedUrl)则为存储中的对象生成带 1 小时有效期的访问链接。分享时把签名 URL 与密码分渠道送达,URL 过期后可随时重新生成。

方案 C:静态托管(Render、Netlify、S3)

把生成的 HTML 文件直接上传到任意静态托管服务即可。由于文件完全自包含、无服务器逻辑,密码保护页面通过浏览器内置的Web Crypto API在纯客户端完成解密,托管方永远接触不到明文。

方案 D:GitHub Pages / Gist

gbrain publish brain/trips/japan-2026.md --out trip.html # 上传到 GitHub Gist 或 Pages 仓库

适合一次性分享(如行程单),不需要独立服务器或云存储账号。

密码保护机制:从加密到解密的完整链路

SKILL.md声明的加密参数,与 src/commands/publish.ts 的encryptContent()完全一致:

项目说明
算法AES-256-GCM带认证标签(auth tag)的认证加密
密钥派生PBKDF2,100,000 次迭代,SHA-256抗暴力破解
盐(Salt)每次加密随机 16 字节相同密码产生不同密文
IV每次加密随机 12 字节与 salt 一样随机化
解密客户端 Web Crypto API(SubtleCrypto)无需服务端鉴权
记住本机localStoragelocation.pathname为键存储

加密端(Node.js,发布时执行)

const salt = randomBytes(16); const iv = randomBytes(12); const key = pbkdf2Sync(password, salt, 100_000, 32, 'sha256'); const cipher = createCipheriv('aes-256-gcm', key, iv); // ... ciphertext + 16 字节 authTag,三者 base64 编码后写入 HTML

加密后的 HTML 中只含window.__SALTwindow.__IVwindow.__CT三段 base64 密文数据,明文不出现于文件任何位置

解密端(浏览器,打开文件时执行)

内嵌的DECRYPT_JS(src/commands/publish.ts)执行完全对称的逆过程:crypto.subtle.importKey('raw', password, 'PBKDF2', ...)deriveKey({ name: 'PBKDF2', salt, iterations: 100000, hash: 'SHA-256' }, ...)crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, combined)。密钥派生参数(100K 迭代、SHA-256)与加密端严格一致,这是两端能够互解的前提。错误密码会触发错误提示与卡片抖动动画;勾选 "Remember on this device" 后,密码按页面路径名存入localStorage,下次打开自动解锁。

自带安全防护

  • 内联 marked.js:发布时把 marked 的 UMD 构建直接读入并写入 HTML(MARKED_JS,见 src/commands/publish.ts),保证产物零 CDN 依赖、完全离线可用(测试inlines marked.js (no CDN dependency)专门断言产物不含cdn.jsdelivr.net);
  • XSS 消毒sanitizeHtml()(src/commands/publish.ts)在marked.parse渲染后移除script/iframe/object/embed/form标签,并清除所有on*事件属性与javascript:协议属性,防止脑页中内嵌的恶意 HTML 在分享文件中执行;
  • 标题转义escapeHtml()(src/commands/publish.ts)对标题做 HTML 实体转义(测试escapes HTML in title验证<script>被转为&lt;script&gt;);
  • 深色模式:内置prefers-color-scheme: dark响应式 CSS 变量主题(测试同样覆盖);
  • 密码字符集generatePassword()(src/commands/publish.ts)默认生成 16 位密码,字符集刻意剔除易混淆字符0 O l 1 I(测试excludes ambiguous characters断言),且每次调用基于randomBytes保证唯一性(测试generates unique passwords验证 20 个密码无一重复)。

更新已发布页面

重新执行发布命令并指向同一输出路径即可:

gbrain publish brain/companies/acme.md --password "same-password" --out shares/acme.html

同一文件、同一 URL(若已托管),内容自动更新。需要提醒的是:必须沿用原密码,否则接收方手中的旧密码将无法解开新文件。

吊销访问权限

  • 本地文件:直接删除文件;
  • 签名 URL:1 小时后自动过期,无需手动吊销;
  • 静态托管:从托管平台移除该文件。

由于整份 HTML 自带解密逻辑、不依赖任何服务端鉴权,"删除文件/撤销 URL"是唯一的吊销手段——这也意味着文件一旦流出,本质上无法远程作废,因此更应在发布前依赖脱敏层把内部数据彻底剥离。

反模式清单

SKILL.md明确列出了四类应当避免的用法:

  1. 不加密就发布——脑内容默认私有,除非用户明确说 "open"、"no password"、"public";
  2. 同一渠道分享密码与 URL——必须分渠道传达,防止被同一窃听方同时截获;
  3. 向用户塞原始 Markdown——gbrain publish能产出精美 HTML,不要用复制粘贴 Markdown 替代;
  4. 手动传播含内部元数据的内容——凡带 frontmatter、Source 引用或 Timeline 章节的内容都不得手工外发,一律交给 publish 命令脱敏。

输出格式约定

发布成功后,CLI 会输出结构化结果摘要,SKILL.md给出的格式如下:

PUBLISHED: [page title] ======================== File: [output path] Encrypted: [yes (AES-256-GCM) / no] Password: [auto-generated password / user-provided / none] Size: [file size] Share the file via: [email / Slack / Airdrop / cloud upload] Share the password via: [a different channel]

实际运行时控制台还会额外输出Published: <outPath>与加密状态说明((password protected, AES-256-GCM encrypted)(no password, content in cleartext),见 src/commands/publish.ts);使用--password且未显式给定时,自动生成的密码会打印在控制台中供 Agent 转达给用户。

源码导览

如需深入实现细节,建议按以下顺序阅读:

  • plugin/skills/publish/SKILL.md —— 技能策略层:触发条件、契约、工作流与反模式;
  • src/commands/publish.ts —— 实现层:makeShareable(脱敏)、encryptContent/generatePassword(加密)、generateHtml(HTML 生成与 XSS 消毒)、runPublish(CLI 入口);
  • test/publish.test.ts —— 测试层:脱敏规则、标题提取、加密随机性、密码字符集、HTML 生成的完整断言矩阵;
  • src/commands/files.ts —— 分享配套:files uploadfiles signed-url的云存储链路。

整套设计的关键收益在于:隐私脱敏与加密不是靠模型临场发挥,而是由确定性代码 + 测试矩阵保证的工程能力,Agent 只需判断"何时发布、是否加密、走哪种渠道",即可安全地把脑内价值输出到墙外。

【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询