Appearance
权限声明
gameSaves 声明开放游戏存档的列表、同步、状态和只读文件能力;不再弹出单独的用户授权确认。旧版兼容权限不会自动获得它,详见游戏存档。
小程序使用受保护的 SDK 能力前,需要在项目根目录的 package.json#heybox.permissions 中声明对应权限。声明只表达当前版本准备使用哪些能力,不会代替平台批准、用户授权,也不代表当前 Host 已经实现该能力。
appProtocol 与协议执行 API 暂不对外开放
appProtocol 权限及 device.executeProtocol() 当前暂不对外开放,开放平台不提供该权限的申请入口。请勿在对外发布的小程序中依赖这项预留能力;声明或本地临时授权不代表对外开放。
声明和本地调试不代表线上批准
network、companion 的申请流程与最高危险等级 appProtocol 的开放限制见下文平台批准。项目可以先完成声明, 并通过 hb-sdk dev 的本地临时权限进行开发调试,但请勿把本地结果视为线上能力已开通,也不要把本地 appProtocol 临时权限当作线上批准。
四层检查
一次能力调用可能依次受到四层约束:
| 层级 | 回答的问题 | 典型结果 |
|---|---|---|
| 开发者声明 | 当前版本是否声明了所需权限? | 运行快照缺少条目时返回 PERMISSION_NOT_IN_SNAPSHOT |
| 平台批准 | 平台是否批准了需要申请的权限及配置? | 未批准或批准范围不足时返回 PERMISSION_DENIED |
| 用户授权 | 当前用户是否同意本次资料或文件访问? | 用户取消或拒绝时返回对应授权错误 |
| Host 支持 | 当前客户端是否实现并开放该 API? | 不支持时返回 METHOD_FORBIDDEN |
通过前一层不代表自动通过后一层。比如线上使用 network 仍需要平台批准;声明 filesystem 后,访问用户文件仍需由用户选择文件或目录;权限和授权都满足时,旧 Host 仍可能因尚未实现文件能力而返回 METHOD_FORBIDDEN。appProtocol 属于平台批准层,其最高危险等级不替代也不豁免其他层的用户授权;但一经批准,该入口即可执行任意协议并绕过其他 SDK 能力权限及专用授权流程,因此平台审核是唯一有效闸门。hb-sdk dev 的有限临时权限见下文,不改变线上批准结果。
在 package.json 中声明
所有权限统一放在 heybox.permissions 对象中。每项都必须显式填写 enabled;enabled: false 的项目不会进入构建产物。
json
{
"heybox": {
"miniProgramId": "mini_program_001",
"platforms": ["android", "ios", "ohos", "windows", "macos"],
"permissions": {
"userInfo": {
"enabled": true
},
"steamLibrary": {
"enabled": true
},
"share": {
"enabled": true
},
"storage": {
"enabled": true
},
"cloud_storage": {
"enabled": true
},
"filesystem": {
"enabled": true
},
"clipboard": {
"enabled": true
},
"leaderboard": {
"enabled": true
},
"network": {
"enabled": true,
"useOfficialDomain": false
},
"companion": {
"enabled": true
}
}
}
}未知权限名、未知配置字段、非 boolean 的配置值都会使构建失败。没有受保护能力需求的严格项目使用 "permissions": {}。Vite 配置、环境变量、CLI 参数和运行时页面都不能覆盖这里的声明。
权限目录
| 权限 | 覆盖 API | 要求 | 配置 | 其他运行条件 |
|---|---|---|---|---|
gameSaves(游戏存档) | gameSaves.listgameSaves.sync列表文件对象的 downloadFile()gameSaves.getLatestStructuredData() | 声明后可用 | 无 | 需要用户明确授权、有效 Steam 登录和支持文件读取的宿主;可按需读取受支持游戏的已有解析概览,不触发解析。 |
userInfo(用户信息) | auth.loginuser.getInfo | 声明后可用 | 无 | 继续执行黑盒登录、用户授权和可信手势规则。 |
steamLibrary(Steam 游戏库) | user.getSteamGameList | 声明后可用 | 无 | 继续执行账号绑定和数据可用性规则。 |
share(分享) | share.copyLinkshare.showShareMenushare.screenshot | 声明后可用 | 无 | 继续执行分享参数校验和 Host 支持检查。 |
storage(键值存储) | storage.getStoragestorage.setStorage | 声明后可用 | 无 | 仅用于简单键值存储,不包含文件系统。 |
cloud_storage(云端存储) | 仅目录元数据;公开 SDK 未开放 | 当前不可调用 | 无 | 目录登记不等于公开 SDK 能力,Web Host 不注册这些方法。 |
filesystem(文件系统) | network.downloadnetwork.uploadfiles.pickFilesfiles.pickDirectoryfiles.saveFilefile.createfile.removefile.existsfile.readTextfile.writeTextfile.readBytesfile.writeBytesfile.statdirectory.createdirectory.removedirectory.existsdirectory.list | 声明后可用 | 无 | 外部文件继续要求有效的用户选择、会话句柄和匹配的读写模式。 |
media(媒体) | media.pick | 声明后可用 | 无 | 图库授权范围仅限本次用户选择的媒体,不包含任意文件或沙盒访问权;继续执行可信手势、Host 能力与会话资源规则。 |
clipboard(剪贴板) | device.setClipboard | 声明后可用 | 无 | 继续执行文本长度和 Host 支持限制。 |
leaderboard(排行榜) | cloud.leaderboard.submitcloud.leaderboard.getListcloud.leaderboard.getCurrentUserEntrycloud.leaderboard.deleteCurrentUserEntrycloud.leaderboard.getInfo | 声明后可用 | 无 | 排行榜必须已创建,用户和资源规则保持不变。 |
network(网络) | network.requestnetwork.downloadnetwork.upload | 声明并获得平台批准 | useOfficialDomain?: boolean,默认 false | 声明后仍需平台批准,并继续执行网络安全策略。 |
companion(桌面辅助应用) | companion.getInfocompanion.getPreparationStatuscompanion.preparecompanion.cancelPreparationcompanion.getActiveSessioncompanion.launchcompanion.session.writecompanion.session.closeStdincompanion.session.terminatecompanion.session.ackOutputcompanion.openAttachmentcompanion.showNotification | 声明并获得平台批准 | 无 | 声明后仍需平台批准,并继续执行可信用户手势、Host 能力和当前版本 Manifest 校验。 |
appProtocol(应用协议执行) | device.executeProtocol | 声明并获得平台批准 | 无 | 最高危险权限:批准后该入口可执行任意协议,并绕过其他 SDK 能力权限及专用授权流程。 |
workspaceCards(工作区卡片) | workspaceCards.requestRefresh | 声明并获得平台批准 | 无 | 需平台批准、Host 支持与有效执行租约;不隐式授予网络或存储权限。 |
network.download() 和 network.upload() 都需要 network 与 filesystem:前者控制外部网络访问,后者控制文件读写。真正开始 I/O 前,两项权限都必须有效;外部文件还需要有效的用户授权句柄和匹配的访问模式。上传的完整示例见文件上传。
内部实现使用 Host 的受信网络端口不会产生额外的公开权限。例如 auth.login() 的方法权限是 userInfo,cloud.leaderboard.* 只需要 leaderboard,cloud.storage.* 只需要 cloud_storage,它们都不额外要求 network;share.copyLink() 只需要 share,不额外要求 clipboard。auth.login() 仍受身份模式限制:平台启用 Steam 账号能力后,无有效网络权限的 local 模式会返回 SERVER_API_REQUIRED,详见用户身份与登录。
无需声明的 API
getHandshakeStateonHandshakeStateChangeonoffenvironment.getInfoenvironment.getInfoSyncshare.getExtraauth.getAccountStateuser.requestFollowAuthoruser.getFollowStatususer.revokeAuthorizationui.showToastui.showLoadingui.hideLoadingviewport.getWindowInfoviewport.setNavigationBarStyleviewport.setDisplaydevice.vibratenavigation.closenavigation.reloadnavigation.openAppPage
白名单是显式目录,不代表未分类的 API 可以免声明。API Reference 中每个小程序侧 callable 都会显示“权限”区块;生成器遇到未分类 API 会直接失败。
平台批准
network、companion、workspaceCards 与预留的 appProtocol 需要平台批准。声明本身不会自动发起申请,平台也可以预先配置批准,但未声明的版本仍不能使用对应能力。
appProtocol 权限及 device.executeProtocol() 暂不对外开放,不提供开发者申请入口。该权限为预留能力,属于最高危险等级:批准后该入口可执行任意协议,并绕过其他 SDK 能力权限及专用授权流程。批准即意味着放弃其他 SDK 权限与专用授权流程对该入口的兜底约束,平台只应批准确有完整协议级需求的受信小程序。
创建小程序并获得 ID 后,即可在开放平台“小程序管理 → 权限申请”中申请 network 或 companion,无需先上传版本。申请需说明用途;网络申请还需填写预计访问域名(仅供审核参考),companion 忽略域名参数。开发者只能申请普通网络权限,不支持申请访问小黑盒官方域名。平台批准绑定小程序,不绑定版本。审批通过后,已绑定该小程序的本地项目声明对应权限即可调试;上传后的版本同样需要声明才能使用。
工作区卡片需要单独获得 workspaceCards 平台批准;当前公开权限申请命令仅支持 network 和 companion,不能通过它申请卡片权限。接入与上线条件见工作区卡片。
Companion 的每次新准备与每次新进程启动还分别需要可信用户手势和 Host 授权;平台批准不能代替这两次授权。appProtocol 不经过这些专用授权流程,因此其安全边界完全依赖平台审核,而不是运行时兜底。
hb-sdk dev 提供的本地临时权限不会带到线上,也不会自动发起申请或修改平台批准记录。
useOfficialDomain 的有效值是开发者请求值与平台批准值的交集:
| 开发者声明 | 平台批准 | 运行时有效值 |
|---|---|---|
false 或省略 | 任意值 | false |
true | false 或未批准 | false |
true | true | true |
useOfficialDomain 省略时按 false 处理。它不会绕过 URL、域名、敏感路径、Header、响应大小、超时或重定向等网络安全策略。
本地开发临时权限
hb-sdk dev 根据 package.json#heybox.permissions 自动为已声明但未获批准的 network、companion、appProtocol 生成当前会话的临时权限,不增加本地开关,也不修改线上批准记录。普通网络可在 Browser Mock 与支持它的真实手机、PC 中调试;真实 Companion 还需合法本地产物、目标平台、摘要绑定和支持它的新 PC Host。
appProtocol 的临时权限与 network、companion 一样只在当前调试会话内有效,用于开发阶段验证协议执行链路。它不能作为线上批准,也不代表该预留能力已对外开放:即使本地临时权限可用,未获线上批准的版本发布后仍会返回 PERMISSION_DENIED。由于该权限可执行任意协议并绕过其他 SDK 能力权限及专用授权流程,本地调试同样会明确标出最高危险等级,不应在共享设备或非受信环境长期开启。
临时权限不包含 workspaceCards,也不会授予 useOfficialDomain。网络敏感路径、凭据过滤、文件授权、可信手势及 Host 支持限制继续生效。业务代码使用原 SDK API,不查询或判断权限来源。
hb-sdk dev 启动前要求登录 CLI、绑定小程序并校验远端配置;启动后的 Browser Mock 不依赖真机签票,真实调试仍需有效启动票并在每次启动时确认临时权限。CLI 失联约 30 秒、票据到期或声明/产物变化会结束旧 Runtime,临时 Companion 进程树一并清理;恢复后重新确认。完整操作见 CLI 指南。
调试台保留常驻“仅本地可用、线上未批准”提示。remote deploy 会警告未批准权限,remote release 将清单并入现有确认,均不会把临时权限带到线上。build/deploy 的 CSP 判定也不消费本地 grant。发布前必须取得所需线上批准并完成真实 Host 验收。
0.8 到 0.9 的迁移
0.8.x:缺少heybox.permissions的存量项目仍按兼容行为运行,但构建和运行时会产生迁移警告。0.8.x:只要字段存在,包括"permissions": {},当前版本就立即进入严格行为;未声明的受保护 API 会失败。0.9.0的预发布版和稳定版:所有版本全面强制声明。旧小程序仍可启动,但未声明的受保护 API 会失败。0.9.0不提供兼容或回滚开关。
迁移时先根据实际调用补齐最小声明,再删除不再使用的权限。不要为了消除错误一次性声明全部权限;权限新增、删除和配置变化会进入版本审核差异。
失败处理
| 错误码 | 含义 | 处理方式 |
|---|---|---|
PERMISSION_NOT_IN_SNAPSHOT | 当前运行快照没有包含所需权限 | 正式入口需发布包含声明的新版本;开发入口更新声明后重新打开调试 |
PERMISSION_DENIED | 已声明,但平台批准缺失或批准配置不足 | 在开放平台“权限申请”页提交申请或核对审核状态 |
METHOD_FORBIDDEN | 当前 Host 未实现或关闭该能力 | 按客户端能力降级,不要反复申请权限 |
| 用户授权相关错误 | 用户取消、拒绝或授权已失效 | 尊重用户选择,仅在新的明确操作中重试 |
详细处理方式见错误处理。身份能力见用户身份与登录,文件与下载见快速开始,桌面辅助应用见受管桌面程序,排行榜见云端排行榜,云存档见云端存储,本地与发布命令见CLI 指南,上架要求见小程序工坊上架规则。
完成检查
- 项目只声明实际使用的权限,且每项
enabled都是 boolean。 - 已按上述平台批准流程处理所需权限,没有把本地临时权限当作线上能力。
- 未在对外发布的小程序中依赖暂不开放的
appProtocol权限或device.executeProtocol()。 network.download()/network.upload()同时声明了network与filesystem。- 用户授权和 Host 支持分别处理,没有把它们误判成声明失败。
- 迁移项目已在
0.8.x补齐声明,不依赖0.9.0的兼容行为。
终端权限申请
先运行 hb-sdk login,并通过 hb-sdk remote create 或 hb-sdk remote bind <mini-program-id> 绑定小程序。第三方主体创建后即可申请,无需先上传版本。第一方主体无需申请,声明并启用所需权限后自动批准;CLI 会拒绝第一方执行 permission apply,Open 管理页也不展示“权限申请”Tab。
bash
# 查看原始审批、本地有效状态、最近申请和审核意见
hb-sdk remote permission list
hb-sdk remote permission list --json
# 申请普通网络权限,域名用逗号分隔
hb-sdk remote permission apply network --reason "访问业务接口" --domains "api.example.com,cdn.example.com"
# 申请桌面辅助应用权限
hb-sdk remote permission apply companion --reason "运行配套桌面辅助应用"list 显示原始审批、当前本地声明下的有效权限、最近申请和审核意见。JSON 中,runtimePermissions 是原始审批快照;permissions 中的 declared、approved、effective 分别表示本地声明、原始批准和最终有效状态。未声明的权限不会因为获批而自动启用,本地有效状态也不代表尚未发布的声明已经在线上生效。
appProtocol 暂不对外开放,不提供公开申请流程。以下 apply 说明仅针对 network 和 companion。
apply 支持 --json,返回申请 ID 和当前审核状态。network 必须填写 1–20 个域名,不含协议、端口、路径或通配符;companion 忽略域名参数,无需(也不应)传入 --domains。理由最多 500 字,不支持申请官方域名权限。
提交会检查当前主体与绑定小程序是否一致。相同待审内容重复提交返回原申请;修改待审域名或理由会提示修改未生效,不覆盖原材料。申请获批后仍需在 package.json#heybox.permissions 中声明权限,提交成功不代表权限已生效。
声明型权限按本地 Manifest 生效,不依赖线上版本已有条目;审批型权限仍需平台批准或允许的本次临时授权。调试台分别展示本地声明、平台批准、临时授权、本地生效与线上状态;线上状态未知时,不代表发布后已生效。
user.requestFollowAuthor() 属于无需声明权限的用户动作,只能关注当前小程序作者。它仍要求可信点击和小黑盒登录,不会授予用户资料权限,也不要求开放 network。