跳到主要内容
TABTAB

导航

权限模型

插件能做什么,不由它写了什么代码决定,而由它在 Manifest 中声明了什么、以及用户是否点了同意决定。

能力桥上的每个方法都带着自己的权限。宿主在方法粒度上判定 —— 不是「这个插件装过了所以随便调」,而是「这一行代码要的这项能力, Manifest 声明过、用户同意过、内容没变过」。

敏感权限与同意门

安装时若插件声明了敏感权限,宿主会在做任何网络与磁盘动作之前返回一个「需要确认」的结果,并把待确认的权限列出来。前端弹窗, 用户点同意后带 approved: true 重新调用,才真正开始下载。

这个顺序是刻意的:同意必须发生在安装之前。 反过来的话,用户点「拒绝」时插件已经在磁盘上了,弹窗只是个事后通知。

clipboard:read

读取剪贴板

包含宿主记录的剪贴板历史与当前系统剪贴板文本 —— 这是用户最容易无意泄露的内容。

安装时需确认
clipboard:write

写入剪贴板

能覆盖用户当前复制的内容。与「读」分开声明,因为两者的风险不对称。

安装时需确认
fs:read

读取本地文件

能搜索本机文件并读取其中一条。读取有闸门:只接受绝对路径、必须是已存在的普通文件、不跟符号链接、单个文件有体积上限 —— 但「能读用户磁盘」这件事本身就必须先问过用户。

安装时需确认
fs:write

写入本地文件

能在家目录下创建或覆盖文件,且写操作不可撤销 —— 判断失误时用户原来那份不会自己回来。宿主限了三件事:只限家目录内、覆盖已有文件必须显式声明、不替你创建目录。它与「读取本地文件」是两条分开的权限,所以只申请读的插件不会顺带拿到写。

安装时需确认
screen:capture

截取屏幕

权限里风险最高的一项。拿它就等于能看见用户屏幕上的一切,包括密码输入框。

安装时需确认
shell:open

用系统默认程序打开

能让操作系统用默认程序打开一个文件或网址。它本身读不到文件内容,却能把任意路径甩给另一个程序去执行 —— 所以宿主把它算作敏感项。

安装时需确认
web

打开网页

能在应用内打开任意网址并与之通信。宿主限制协议与来源,不允许插件据此读取任意本地文件。

安装时需确认

非敏感权限

notification无需单独确认

桌面通知

能弹出带插件名的系统通知,滥用会变成用户关不掉的骚扰;但它看不到任何数据,宿主因此不单独征求同意(见 permission.rs 的 is_sensitive)。

storage无需单独确认

私有存储

读写本插件自己命名空间下的键值对。与其它插件互不可见,用户卸载时可选择一并清除。

带参数的权限

权限不只是一组固定代号,也有带参数的形态:http:${domain}。 它把授权范围收窄到具体域名 —— 插件能请求网络,但只能请求它自己写进 Manifest 里的那个域名。

包内交叉校验

索引条目声明的权限是用户看到并同意的那一份;包内 Manifest 声明的权限是 实际会运行的那一份。两者必须满足:包内不得多于索引。

不做这个交叉比对,用户在弹窗里点头同意的是一份清单,装进去的却是另一份 —— 卡片上写的和跑起来的不一致,这件事没有任何一层会报错。

同意记录怎么失效

  • 升级时新增权限会重新弹窗。同意记录是「插件 id → 当时同意的权限集合」, 集合变了就是一次新的决定。
  • 卸载会撤销授权。哪怕用户清数据、哪怕目录删不干净,重装同 id 也会重新问一次 —— 他当初点的「同意」可能是几个月前对另一个包的同意。
  • 停用不动授权。停用是可撤销的开关,它不该顺手把用户对权限的 决定也一并丢掉。

调用失败时你会看到什么

能力桥返回的错误有固定几种,每一种都对应一件具体的事:

code含义
INTERNAL宿主内部错误。这类不该出现在正常路径上。
INVALID_PARAMS参数类型或数量不对。桥的每个方法都有固定签名,见能力桥 API。
PERMISSION_DENIED这项能力没有声明,或用户没同意。先去查 Manifest,不是查代码。
UNKNOWN_METHOD宿主版本还没有这个方法。检查 minHostVersion。