权限声明
场景需要在 scenario.json(声明式场景)或 getPlugin().permissions(编程式场景)中声明所需权限。 运行时由 PermissionGuard 在每次工具执行前校验,未声明对应权限的工具调用会被拒绝。
- 权限枚举定义:
src/shared/protocols/scenario-arch.ts→ScenarioPermission - 校验实现:
src/scenario-system/core/PermissionGuard.ts - 可视化选择:场景构建器的「权限」配置项(
SCENARIO_PERMISSION_OPTIONS)
权限标识(ScenarioPermission)
| 权限标识 | 分组 | 说明 |
|---|---|---|
filesystem:read | 文件系统 | 读取文件内容、列出目录、搜索文件与代码库 |
filesystem:write | 文件系统 | 写入 / 创建 / 删除文件与目录 |
database:connect | 数据库 | 连接场景自有数据库 |
database:query | 数据库 | 执行 SQL 查询(sql_query) |
network:request | 网络 | 发起网络请求(网络搜索、网页读取) |
terminal:execute | 终端 | 执行终端命令(run_command)、终端输出读取/输入/终止,以及 Git 写操作(git_commit、git_branch、git_sync、git_worktree、git_audit) |
clipboard:read | 交互 | 读取系统剪贴板 |
clipboard:write | 交互 | 写入系统剪贴板 |
notification:send | 交互 | 发送系统通知 |
system:info | 系统 | 读取系统信息(hostname / 平台 / 内存等) |
mcp:call | 系统 | 调用 MCP 插件工具 |
以上 11 项即为权限的完整可声明集合,其他写法会被 PermissionGuard.validatePermissions() 判为无效值。
工具 → 权限映射
PermissionGuard 内置工具与权限的映射表(TOOL_PERMISSION_MAP):
| 权限标识 | 覆盖工具 |
|---|---|
filesystem:read | read_file、list_directory、search_files、codebase_search、git_status、git_diff、git_log |
filesystem:write | write_file、create_file_or_folder、delete_file_or_folder |
database:query | sql_query |
terminal:execute | run_command、read_terminal_output、send_terminal_input、stop_terminal、git_commit、git_branch、git_sync、git_worktree、git_audit |
network:request | web_search、read_url |
clipboard:read | clipboard_read |
clipboard:write | clipboard_write |
notification:send | notification_send |
system:info | system_info |
无需权限声明的工具
未出现在上表中的工具视为安全工具,直接放行,例如 ask_user、todo_write、remember、 knowledge_search、companion_control、get_lint_errors、find_references、go_to_definition、 get_hover_info、get_document_symbols、data_transform、csv_analyze、chart_generate、 statistical_test 等。
⚠️ 注意:
edit_file当前不在权限映射表中,因此不需要filesystem:write。 文件写入的防误用保护由文件写入策略层负责(src/renderer/intelligence/toolkit/fileWritePolicy.ts): 禁止用write_file局部修改已有文件,引导模型改用edit_file。该行为约束与场景权限无关。
MCP 工具权限
所有以 mcp_ 为前缀的工具统一要求 mcp:call,不会逐个登记到映射表中。未声明时调用会被拒绝:
Scenario "xxx" does not have the required permission "mcp:call" to call MCP tool "yyy".声明方式
声明式场景(scenario.json)
{
"id": "my-scenario",
"permissions": ["filesystem:read", "filesystem:write", "network:request"]
}2
3
4
编程式场景(module.ts)
getManifest() {
return {
id: 'my-scenario',
version: '1.0.0',
permissions: ['filesystem:read', 'terminal:execute'],
}
}2
3
4
5
6
7
校验时机与结果
校验优先级(PermissionGuard.checkTool):
- 项目级黑名单(
blockedTools)→ 拒绝,missingPermissions: ['project:blocked'] - 项目级白名单(
allowedTools,非空时生效)→ 不在白名单则拒绝,missingPermissions: ['project:whitelist'] - MCP 工具 → 要求
mcp:call - 场景级权限 → 命中映射表但未声明对应权限则拒绝,
missingPermissions: [所需权限] - 未命中映射表 → 放行
拒绝结果结构:
interface PermissionCheckResult {
allowed: boolean
missingPermissions: MissingPermission[] // ScenarioPermission | 'project:blocked' | 'project:whitelist'
reason?: string
}2
3
4
5
被拒绝时客户端会记录告警日志:
[PermissionGuard] Scenario "xxx" lacks permission "terminal:execute" for tool "run_command"项目级权限覆盖
除场景自身声明外,工作区可对权限做细粒度收敛(ProjectPermissionConfig):
interface ProjectPermissionConfig {
/** 允许的工具白名单(为空则不过滤) */
allowedTools?: string[]
/** 禁止的工具黑名单(优先级最高) */
blockedTools?: string[]
}2
3
4
5
6
配置按工作区存储,键名为 project:<workspacePath>:permissions。 PermissionGuard 构造时若传入 workspacePath 会自动加载,也可通过 updateProjectConfig() / resetProjectConfig() 动态调整。
预定义权限组
PermissionGuard 内置权限组常量(PERMISSION_GROUPS),可用 PermissionGuard.expandPermissionGroup(groupName) 展开为具体权限列表:
| 权限组 | 展开结果 |
|---|---|
basic | filesystem:read |
file-access | filesystem:read、filesystem:write |
networking | network:request |
full-filesystem | filesystem:read、filesystem:write |
full-terminal | terminal:execute |
full-database | database:connect、database:query |
all | 全部 11 项权限 |
⚠️ 权限组是代码内的 API,用于宿主侧批量收敛权限。
scenario.json的permissions字段只接受上表中的具体权限标识,写组名(如"all")不会生效。
最小权限原则
建议只声明场景实际需要的权限:
// ✅ 推荐:只声明需要的权限
{
"permissions": ["filesystem:read", "network:request"]
}
// ❌ 避免:声明过多不需要的权限
{
"permissions": [
"filesystem:read", "filesystem:write",
"database:connect", "database:query",
"network:request", "terminal:execute",
"clipboard:read", "clipboard:write",
"notification:send", "system:info", "mcp:call"
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
场景未声明任何权限也是合法且推荐的默认状态。
发布前检查
场景构建器的发布前检查(PrePublishChecklistService)会扫描 permissions 并给出风险提示。 被标记为危险的权限:
| 权限标识 | 风险说明 |
|---|---|
filesystem:write | 可写文件系统,请确认是否真有必要 |
terminal:execute | 可执行任意命令,仅在脚本化场景才声明 |
system:info | 可读取系统信息(hostname / 平台 / 内存等) |
network:open-external | 可打开外部 URL,存在钓鱼风险(预留项,尚未纳入 ScenarioPermission) |
场景发布到市场时,管理员会审核权限声明是否合理。声明过多不必要权限的场景可能被拒绝上架。
## 权限审核
当场景发布到市场时,管理员会审核权限声明是否合理。如果场景声明了过多不必要的权限,可能会被拒绝上架。2
3
4

