PKU harness

PKU harness Cloud

PKU harness Cloud 是一套可选的插件后端标准,包含存储、中继通道、推送、文件和服务端函数。官方实例、自建服务器或任何符合标准的服务器都可以提供这些服务。数据默认端到端加密,云端不保存校园身份。

大多数插件只在手机上运行,但有些功能需要服务器。例如,把校园卡付款码实时分享给一位没有安装 App 的朋友,或者在几台设备之间同步一小份数据。PKU harness Cloud(下文简称「云服务」)是为这类功能制定的一套后端标准。它规定了服务器要提供哪些接口,以及 App 和插件如何使用这些接口。

设计云服务时,我们的目标是让你在使用服务器的同时不必信任它。下面几段说明这一点是怎样做到的。

设计原则

数据在离开手机之前就已经加密。这种方式叫作端到端加密(end-to-end encryption,E2E):只有发送方和接收方持有密钥,服务器只负责转发和保存密文,自己无法解密。

云端不保存你的校园身份。服务器只通过设备生成的一对密钥来识别设备,不知道你的学号和姓名,也收不到你的校园账号密码或登录会话。

同一份协议可以由多家服务商提供。你可以使用官方实例、自己部署的参考服务器,或者任何实现了这份协议的服务器地址。插件调用的接口完全相同,也无法分辨当前连接的是哪一家。

App 会把各个插件隔离开。App 是运行插件的一方,我们称它为「宿主」。宿主给每个插件一个只属于它自己的云服务客户端,每个插件有独立的 token、独立的存储空间,并且要单独获得你的授权。

AI 助手只能通过插件提供的工具使用云服务。它看不到云服务的凭据和 token,也看不到分享链接。

当前进度(2026-10-24)

官方云服务实例还没有部署。在它上线之前,如果要使用云服务,请在「设置 → 云服务」里填写自建服务器的 URL。

已经完成的部分有:协议 v1(@pku-harness/cloud-protocol)、SDK 类型、参考服务器(packages/cloud-server),以及 App 内的云服务客户端。客户端支持设备身份、按插件绑定和授权、端到端加密的存储与通道,并在「设置 → 云服务」里提供连接测试。第一个使用云服务的插件是 card-share,它实时分享校园卡付款码,全程端到端加密。推送服务(push)还没有完成,参考服务器目前对它返回 501 unsupported。

官方实例上线后会刻意保持精简,只提供三样东西:实时分享用的中继(通道和信箱,服务器只转发看不懂的密文),小容量的端到端加密存储,以及静态查看页。插件的服务端函数已经在参考服务器里实现,但官方服务器不开启这项功能。

三个组成部分

云服务由三部分组成。第一部分是服务定义,也就是 SDK 里的类型和一份带版本号的 HTTP 协议。第二部分是服务商,即真正运行服务器的一方。第三部分是使用方,也就是调用云服务的插件。

部分内容位置
服务定义SDK 类型(CloudManifest、PluginCloud)和 HTTP 协议(/v1)@pku-harness/sdk(cloud.ts)、@pku-harness/cloud-protocol、API 参考
服务商官方实例、开源参考服务器(自建)、任何符合标准的 URL服务商与自建
使用方插件,通过 ctx.cloud 或 props.cloud 访问插件指南

云服务提供的服务

协议定义了五种服务。服务商可以只提供其中一部分。

store 是键值存储。每台设备上的每个插件各有一块独立的空间,按 (device, plugin) 划分。它支持版本号(If-Match)和过期时间(time to live,TTL)。如果插件声明了 e2e,值会先在手机上加密再上传。

channels 是实时分享用的中继通道。设备开一个通道,查看者用分享链接加入,服务器在两者之间转发数据帧。通道始终端到端加密,每个查看者的密钥都由分享链接里的密钥派生。

push 用于推送 token 和定时推送。这项服务还在计划中,官方实例不会提供。推送内容会加密,服务器只知道发送时间。

files 是文件存储,目前也在计划中。

functions 是插件在 PLUGIN.md 的 server: 段里声明的服务端函数,下文有详细说明。官方服务器不开启这项功能。服务端函数必须事先声明并经你同意,它也是整个云服务里唯一可能处理明文的地方。

App 通过 GET /v1/meta 查询服务商提供哪些服务。如果插件在 uses 里列出的某项服务对方不提供,App 会把这个插件标为不可用,并说明原因。

一次请求的流程

下面以插件写入一条存储为例。插件调用 ctx.cloud.store.put,宿主先检查授权、插件清单里的 uses 和 e2e。如果插件声明了 e2e,宿主用 XChaCha20-Poly1305 算法加密这个值。然后宿主用设备的 Ed25519 密钥签名一段挑战,换取一个有效期 10 分钟的 token,附在请求上发给服务商。服务商从 token 里读出设备和插件,确定存储空间,最后把密文保存下来。

plugin ──ctx.cloud.store.put(key, value)──► host(为这个插件绑定的客户端)
          │ 检查授权、清单里的 `uses` 和 `e2e`
          │ 声明了 e2e 时加密值(XChaCha20-Poly1305)
          │ 签发或刷新 10 分钟有效的 token(Ed25519 签名挑战)
          ▼
        provider  PUT /v1/store/<key>   Authorization: Bearer <token>
          │ 存储空间 = token 里的 (deviceId, plugin)
          ▼
        保存密文

服务端代码在哪里运行

插件需要服务器参与时,有三种做法。我们建议按下面的顺序考虑。

  1. 标准服务,包括 store、channels、mailbox、push 和 files。每个符合标准的服务器都会实现它们,服务器上不运行任何插件代码。能用这一层解决问题时,请优先使用它。
  2. 插件服务端函数,写在 PLUGIN.md 的 server: 段里。服务器用和 App 相同的解释器执行它们。官方服务器不开启这项功能。
  3. 外部后端,即任何实现了这份协议的 URL。插件要在清单里声明它(backend: { kind: 'external', url }),并经你同意后才能使用。

服务端函数

官方服务器不开启

请让插件在手机端完成工作,或者使用你自己的后端。设计文档 docs/CLOUD-FUNCTIONS.md 已暂停推进:已有的功能保留,但集合、定时任务、推送、群组和 webhook 都不再开发。

插件文档可以声明服务端函数。服务端函数使用的步骤和表达式与插件工具相同,只是在服务器上执行。下面是一个例子:

PLUGIN.md(frontmatter 节选)
cloud:
  disclosure: { zh: ['你输入的名字会发到云端服务器。'], en: ['The name you enter is sent to the cloud server.'] }
server:
  network: [api.example.org]        # 服务端步骤可以访问的主机(HTTPS)
  secrets: [API_KEY]                # 由运营者保管,只能在请求模板里使用
  functions:
    stats:
      effect: read
      access: public                # 目前支持 user(默认)和 public;peer、group、webhook 尚不支持
      cache: 30s
      steps:
        - let: c
          request: { url: 'https://api.example.org/v1/count', headers: { authorization: 'Bearer ${secrets.API_KEY}' } }
          as: json
      return: "{ count: c.count }"

使用服务端函数时要注意以下几点:

  • 写了 server: 段,就等于声明了 cloud.uses: [functions],并且必须同时写 cloud.disclosure。
  • 服务端步骤有自己的一组宿主能力:按用户隔离的服务端键值存储(kv.get/set/delete),以及 crypto.sha256、crypto.hmacSha256(按名字引用密钥)和 crypto.randomId。服务端步骤访问不了校园服务。caller.id 是设备在这个插件下的假名。
  • 手机端通过 cloud.call { fn, input } 能力调用函数。小组件也可以绑定 { fn },而不只是 { tool }。
  • token 里记录了你同意时的插件文档版本(链接加内容哈希),服务器只运行这个版本。是否运行还取决于运营者的策略 CLOUD_FN_POLICY,可选值为 verified、allowlist 和 open。相关环境变量见参考服务器的 README。

继续阅读

  • 插件指南:声明 cloud、获取授权、使用 store 和 channels。
  • 安全:设备密钥、工作量证明、token、信封和分享链接。
  • 服务商与自建:选择服务商,以及运行参考服务器。
  • @pku-harness/cloud-protocol:服务器和查看页共用的 schema 与加密实现。
  • API 参考:全部接口,由 OpenAPI 3.1 规范生成。

本页目录