插件的所有能力都要在 requested_permissions 中声明。声明只是申请上限,最终以用户授权为准;宿主在每次调用时还会再校验清单、授权、发行策略和当前会话。
0.4.5 新增 pages/profile_items/editors/windows 及 ui.window* 权限,见出现位置(草稿)。
声明格式
"requested_permissions": [
{ "permission": "storage.kv", "worker": "host", "optional": true },
{
"permission": "net.fetch",
"worker": "main",
"optional": false,
"scope": { "domains": ["api.example.com"], "methods": ["GET", "POST"] }
}
]
| 字段 | 必填 | 约束 | 说明 |
|---|---|---|---|
permission | 是 | 15 项之一,见权限一览 | 权限名。 |
worker | 是 | 本地标识或 host | 权限归属:真实的 Worker id,或代表界面侧(Surface)的 host。 |
optional | 否 | 布尔,默认 false | 可选权限由用户在安装时勾选,可以在之后撤销。 |
scope.domains | 否 | ≤64 项,如 api.example.com、*.example.com、host:port | 网络请求的域名范围。 |
scope.methods | 否 | GET | HEAD | POST | PUT | PATCH | DELETE | 允许的 HTTP 方法。 |
scope.paths | 否 | ≤64 项 | 可读取的知识源路径,仅用于 fs.source.read。 |
scope.allow_insecure_http | 否 | 布尔,默认 false | 是否允许明文 HTTP。 |
scope 的使用规则:net.fetch 可以带 domains 和 methods,但不能带 paths;fs.source.read 必须带 paths;其余权限不能带 scope。
权限归属:host 与 Worker
同一个权限名,归属不同,含义也不同。宿主为两者分别记录授权,互不相通:给界面侧 host 的授权不能让 Worker 联网,反之亦然。
| 归属 | 可用的权限 |
|---|---|
宿主级(host) | net.fetch、system.metrics.read |
Workspace 作用域(可写 host,按工作区授权) | agent.context、agent.events、storage.kv、storage.blob、files.dialog、runtime.ai、ui.open_external、agent.trigger、agent.capture |
| 必须是真实 Worker id | fs.source.read、service.invoke、events.connect,以及给 Worker 用的 net.fetch |
Workspace 作用域权限与 worker 字段无关,不需要为了挂权限而建一个空 Worker。
授权方式
- 必需权限(
optional: false):用户确认安装即授予。 - 可选权限(
optional: true):在安装预览中由用户勾选,之后可以在插件详情里开启或撤销。插件必须处理未授权的情况,展示启用指引,不要循环重试。 - Worker 权限:安装后在 Worker 授权中单独记录,与界面侧授权分开。
- 升级:界面侧授权按权限名记录,升级时增删
scope或connect不会重置;必需权限自动授予,可选权限保留用户原来的选择。
权限一览
下表中的「界面名称」是桌面端安装预览和插件详情中显示的名称。
| 权限 | 界面名称 | 归属 | 用途 |
|---|---|---|---|
fs.source.read | 读取知识源 | Worker | Worker 读取用户授权的知识源文件。 |
net.fetch | 网络请求 | host 或 Worker | 由宿主代理发出 HTTP 请求。 |
net.local | 访问局域网与本机服务 | Worker(与同一 Worker 的 net.fetch 或 events.connect 配对) | 允许网络请求和事件连接访问局域网与本机地址,见net.local。 |
storage.kv | 键值存储 | Workspace | 保存少量设置和索引。 |
storage.blob | 图片与文件存储 | Workspace | 保存文档、图片、音视频等大块数据。 |
events.connect | 长期事件连接 | Worker | 由宿主维持 SSE、WebSocket 或 Webhook 中转连接。 |
files.dialog | 系统文件对话框(打开/导出) | Workspace | 让用户通过系统对话框导入或导出文件。 |
runtime.ai | — | Workspace | 调用宿主托管的 AI 运行时,仅限官方来源。 |
agent.context | Agent 上下文 | Workspace | 向当前对话的 Agent 发布插件状态快照。 |
agent.events | Agent 事件 | Workspace | 接收 Agent 发来的动作并修改插件状态。 |
ui.open_external | 使用系统浏览器打开外链 | Workspace | 在用户点击时用系统浏览器打开网址。 |
agent.trigger | 主动触发 Agent 对话 | Workspace | 插件主动向主对话发送一条消息。 |
agent.capture | 向 Agent 提供插件区域截图 | Workspace | 把插件界面的指定区域截图提供给 Agent。 |
service.invoke | 调用服务 | Worker | 调用全局 Worker 服务。 |
system.metrics.read | 读取聚合系统指标 | host | 读取 CPU、内存等聚合系统指标。 |
逐项说明
fs.source.read
- 用途:Worker 通过
host.fs.stat和host.fs.read读取知识源文件。 - 授权:归属真实 Worker id,必须带
scope.paths。 - 注意:Worker 只拿到相对路径或不透明的文件令牌,拿不到真实根目录。令牌绑定插件、版本、Worker、授权和有效期,撤权、停用、升级后失效。
net.fetch
- 用途:界面侧调用
stabledgePlugin.net.fetch,或 Worker 调用host.net.fetch。 - 授权:界面侧写
"worker": "host";Worker 侧写真实 Worker id。两者是两份独立授权。声明了connect的工作区或顶部栏项必须同时申请 host 的net.fetch。 - 注意:Worker 侧检查以下几项:没有相应权限时返回
PLUGIN_WORKER_PERMISSION_DENIED,协议不是 http/https 时返回PLUGIN_HOST_NET_DENIED;带credential_refs的请求还必须用 https 并命中凭据的allowed_origins,否则返回PLUGIN_CREDENTIAL_ORIGIN_DENIED。错误统一以 JSON-RPC-32010返回,message为CODE:msg。不能带scope.paths。详见存储、文件与网络。 - 范围:界面和 Worker 发起的网络请求,默认都只能访问公网;访问局域网和本机服务需要单独申请
net.local,安装时由用户单独确认,之后可以撤销。
net.local(访问局域网与本机服务)
- 用途:允许
net.fetch的请求和events.connect的连接访问局域网与本机地址,例如本机运行的模型服务或局域网内的设备。界面侧的stabledgePlugin.net.fetch和 Worker 侧的host.net.fetch都受它约束。未声明net.local时,指向本机、局域网或云元数据地址的请求和连接都会被拒绝。未获授权时,这类请求和连接返回PLUGIN_HOST_NET_PRIVATE_TARGET。哪些地址算局域网与本机地址,见存储、文件与网络 · 局域网与本机地址。 - 授权:必须与同一个
worker下的net.fetch或events.connect至少一项一起声明;单独声明或声明在其他 Worker 上,安装时返回PLUGIN_MANIFEST_INVALID,打包脚本报错为net.local must be requested together with net.fetch or events.connect for the same worker。 - 展示与撤销:属于敏感权限,安装页会单独列出,显示为「访问局域网与本机服务」,并附风险提示。用户可以在插件的 Worker 设置里授予或撤销。
- 注意:云元数据地址
169.254.169.254和fd00:ec2::254始终拒绝,获得net.local也不能访问。
storage.kv
- 用途:
storage.get/set/delete,保存设置、索引和blob_id。 - 授权:Workspace 作用域,可写
host。 - 注意:单项上限 64 KiB,每个插件总量 1 MiB。文档、缩略图、Base64 数据和无界数组不要放进 KV,改用
storage.blob。
storage.blob
- 用途:
blob.put/delete/list/resolve,保存大块数据;也是文件拖放、文件对话框、截图和blob类型网络响应的前提。 - 授权:Workspace 作用域,可写
host。 - 注意:单个 Blob 默认上限 64 MiB,每个插件默认总量 512 MiB,用户可以在「设置 → 插件」中调整,以
storage.getUsage()返回值为准。声明drops、files.dialog或capture_providers时必须同时申请。
events.connect
- 用途:让宿主为
event_channels建立长连接,并把事件投递给 Worker。 - 授权:归属处理事件的真实 Worker id;未授权时不建立连接。
- 注意:撤销该权限、删除凭据或停用插件后,连接立即停止。连接目标同样受局域网与本机地址规则约束。
files.dialog
- 用途:
files.openFile打开系统对话框导入文件,files.exportBlob把 Blob 导出到用户选择的位置。 - 授权:Workspace 作用域,可写
host;必须同时申请storage.blob。 - 注意:插件始终拿不到系统路径;导入的文件以 Blob 形式交给插件。
runtime.ai
- 用途:调用清单
ai_runtime中声明的具名请求。 - 授权:与
ai_runtime必须成对出现,缺一拒绝安装。 - 注意:只对官方来源开放,第三方发布者的包一律拒绝安装。
agent.context
- 用途:
context.publish发布插件状态快照,Agent 通过它读取当前工作区。 - 授权:Workspace 作用域,可写
host。 - 注意:有工作区时,
agent.context和skills必须成对出现。可绑定 Agent 的工作区里,该权限不能设为可选。快照序列化后不超过 64 KiB,且不要包含凭据、路径或无界正文。
agent.events
- 用途:通过
events.on("agent.custom", …)接收 Agent 发起的动作。 - 授权:Workspace 作用域,可写
host。允许 Agent 写入时不能设为可选;只读绑定可以不申请。 - 注意:每个动作处理完都要提升快照版本并发布一次,否则宿主会判定动作未生效。
ui.open_external
- 用途:
ui.openExternal(url)用系统浏览器打开网址。 - 授权:Workspace 作用域,可写
host,通常设为可选。 - 注意:只能在真实的用户点击等激活事件内调用,只接受绝对 http(s) 网址。不要用
window.open或顶层跳转代替。
agent.trigger
- 用途:
agent.trigger({ message })主动向主对话发送一条消息。 - 授权:Workspace 作用域,可写
host,建议设为可选。 - 注意:只有当前聚焦、已发布快照、绑定有效的工作区可以触发;已有 Agent 回复进行中、失焦、撤权或被限流时调用失败。要让用户清楚什么时候会自动发送,失败时在界面上提示,不要反复重试。
agent.capture
- 用途:配合工作区的
capture_providers,把插件界面的指定区域截图交给 Agent。 - 授权:Workspace 作用域,可写
host;必须同时申请storage.blob。 - 注意:只能截取清单中声明的插件区域,返回 PNG 和准确尺寸;不能截取整个屏幕、宿主界面、其他插件或其他应用。
service.invoke
- 用途:Worker 通过
host.service.invoke调用required_services中声明的全局 Worker 服务。 - 授权:归属真实 Worker id,并且必须与该 Worker 的
required_services对应。 - 注意:被调用的服务不继承调用插件的权限。可选依赖缺失时,插件要有明确的本地降级路径。
system.metrics.read
- 用途:界面侧通过
services.invoke("host.system_metrics", "sample", {})读取聚合系统指标,常用于顶部栏监视器。 - 授权:宿主级权限,写
"worker": "host"。 - 注意:
services.invoke只能调用宿主已登记的服务和方法,不是通用的命令通道。
组合约束
以下约束在打包和安装时校验,不满足即拒绝:
| 条件 | 要求 |
|---|---|
申请 files.dialog | 同时申请 storage.blob |
工作区声明 drops | 申请 storage.blob |
工作区声明 capture_providers | 申请 agent.capture 和 storage.blob |
有工作区且提供 skills | skills 与 agent.context 成对出现 |
| 可绑定 Agent 的工作区 | agent.context 不能设为可选;允许 Agent 写入时 agent.events 也不能设为可选 |
声明 ai_runtime | 与 runtime.ai 成对出现,仅限官方来源 |
工作区或顶部栏项声明 connect | 申请 "worker": "host" 的 net.fetch |
申请 net.local | 同一个 worker 下同时申请 net.fetch 或 events.connect |
声明 required_services | 对应 Worker 申请 service.invoke |
声明 event_channels | 对应 Worker 申请 events.connect |
声明 credentials | 对应 Worker 申请 net.fetch 或 events.connect |
建议
- 只申请当前功能真正用到的权限,不为“以后可能需要”预留。
- 非核心能力(外链、主动触发 Agent 等)设为可选,并在界面上处理未授权状态。
- 权限被撤销、插件被停用或升级后,旧的会话和令牌都会失效;插件要能从这些状态恢复,而不是白屏。