PRIVAD
PRIVAD
私有扩展商店

关于 PRIVAD

自建私有扩展分发渠道:自己签、自己发、自己更新,不受公共商店政策约束。

为什么自建分发

公共商店的审核规则与部分扩展的功能天然冲突。

浏览器扩展在公共商店上架时,会被要求功能单一、不得干扰其他扩展、不得绕过站点的嵌入保护等。这对大多数扩展是合理约束,但对「厂商官网内嵌增强」这类需求就变成了硬性阻碍:

能力公共商店自建分发
内嵌禁止 iframe 的站点视为绕过站点嵌入保护允许,发布方自行负责
剥离 XFO / CSP 响应头通常被判定为规避安全机制允许
强制内嵌 PDF / 拦截下载易被判为干扰浏览器行为允许
审核周期数天至数周,被驳回需重来随你节奏,改完即发
版本回滚需重新提交审核替换文件即可
权限披露要求强制数据披露表单自行在页面说明(本商店逐项列出)
代价是你要自己承担审核责任。不受审核约束 ≠ 不需要向使用者负责。本商店的做法是:每个扩展详情页逐项列出权限与用途,让安装前就能判断是否可信,而不是装完再猜。

技术构成

零依赖构建,产物为标准 CRX3 容器。

环节实现
商店前端纯静态 HTML + CSS + 原生 JS,无框架、无构建步骤;数据源为静态 dist/catalog.json + 云端目录合并
浏览器打包site/pack.js —— 浏览器内完成 CRX3 签名(WebCrypto),私钥不出本机
命令行打包器tools/build-crx.js —— 手写 ZIP(store) + Protobuf CrxFileHeader + RSA-SHA256,零第三方依赖
签名密钥每个扩展一把 RSA-2048,落盘 tools/keys/<id>.pem,不随包分发
产物校验tools/verify-crx.js —— 33 项断言,独立解析容器每一层结构
发布接口Makers 云函数 api/catalog.js —— 令牌鉴权、产物入库、目录查询;api/file/ 下发产物
云端存储平台对象存储(Blob),按 ext/<id>/ 与 meta/<id>.json 前缀建模,强一致读
更新清单Google Update 协议 v2 的 update.xml,配合浏览器策略实现静默升级
安装方式装扩展助手生成策略文件(免管理员权限),或手动侧载

如何上架一个新扩展

两条路径:浏览器打包上传(推荐)或命令行构建部署。

路径一 · 浏览器打包上架(推荐)

  1. 选扩展目录

    在打包上架里点选扩展文件夹,需直接包含 manifest.json。

  2. 选签名密钥

    用已有 .pem 保持扩展 ID 不变,或点「生成新密钥」首次创建并立即保存。

  3. 填商店信息并生成

    名称、简介、分类、标签。图标会自动从 manifest 提取并内联,无需手动上传。

  4. 填发布令牌 → 上传

    产物直接入库,商店首页立即生效,无需重新部署。私钥不出本机。

路径二 · 命令行(多扩展 / 批量 / CI)

  1. 放入扩展源码

    目录名即扩展 id:extensions/<ext-id>/,内含 manifest.json 与全部运行文件。

  2. 写商店元数据

    同目录下新增 store.json,描述名称、摘要、分类、标签、功能要点、权限用途、隐私说明、FAQ 与更新历史。字段缺失时页面会自动降级,不至于白屏。

  3. 构建并部署

    node tools/publish.js 一条命令完成打包 → 校验 → 组装;首跑自动为该扩展生成密钥。

node tools/publish.js && edgeone makers deploy _deploy -n privad

项目结构

# 目录结构
privad/
├─ site/                 # 静态页面(部署时拍平到根)
│  ├─ index.html         # 商店首页
│  ├─ extension.html     # 扩展详情页
│  ├─ package.html       # 打包上架(浏览器打包 + 上传)
│  ├─ install-helper.html # 装扩展助手(生成策略)
│  ├─ install.html / privacy.html / about.html
│  ├─ style.css / common.js
│  └─ pack.js            # 浏览器端 CRX3 打包内核
├─ extensions/           # 扩展源码(命令线路径用)
│  └─ <ext-id>/
│     ├─ manifest.json
│     └─ store.json      # 商店元数据
├─ cloud-functions/      # Makers 云函数
│  ├─ api/catalog.js     # 目录查询 / 上传(令牌鉴权)
│  ├─ api/file/…         # 产物下发
│  └─ api/ext/…          # 下架
├─ tools/
│  ├─ build-crx.js       # CRX3 打包器
│  ├─ verify-crx.js      # 产物校验器
│  ├─ verify-pages.js    # 真实引擎渲染验证
│  ├─ publish.js         # 一键构建
│  └─ keys/              # 签名私钥(切勿公开)
├─ package.json          # 云函数依赖声明
├─ store.config.json     # 站点配置(baseUrl)
└─ _deploy/              # 部署根目录(上传这个)
   ├─ catalog.json
   ├─ <ext-id>-<version>.crx / .zip
   └─ <ext-id>-update.xml

关于签名密钥

扩展 ID 由公钥派生,因此密钥即身份:

私钥泄露等于身份被冒用。拿到私钥的人可以签出与本扩展 ID 相同的包,并配置更新源劫持升级。因此私钥绝不能进公开仓库、也不应随产物分发。

已知限制

场景表现
FirefoxdeclarativeNetRequest 的 modifyHeaders 对 XFO / CSP 支持不完整,依赖剥除响应头的功能会降级失效。
Safari不支持 CRX3 侧载,需转为 WebExtension 打包另行分发。
移动端Chrome Android / iOS 不支持桌面扩展,本商店仅面向桌面浏览器。
个人侧载更新无自动更新通道(浏览器只为受管设备检查更新源),需手动重新下载覆盖。
PRIVAD · 自建私有扩展商店