# dsh-plugin-tool-guard — 接口文档(API Reference) > 本文档描述插件的全部对外接口:Harness 事件、大模型工具(guard_*)、HTTP 端点、配置项、以及卸载行为。 > 源码入口:`src/index.ts`。 --- ## 1. Harness 事件 ### 1.1 `tools/pre-execute`(核心拦截) Harness 原生 waterfall 事件(等价于 PRD 中的 `tool:before`)。插件在每次工具调用执行前触发规则引擎检查。 ``` 监听器签名: (exec: ToolExecution, next: () => Promise) => Promise ``` - `exec.name` — 工具名 - `exec.arguments` — 解析后的入参(只读) - `exec.agent.session.id` — 会话 ID(会话隔离用) - `exec.agent.session.header.cwd` — 会话工作目录(路径白名单兜底根) **决策语义(组合式,不短路其他安全监听器):** | 插件决策 | 行为 | |---|---| | `{ kind: 'deny', reason }` | 直接拒绝,返回友好错误给大模型(其他下游监听器不再执行) | | `{ kind: 'allow' }` | 先调用 `next()` 让下游 pre-execute 监听器继续检查,再返回最终结果 | **异常安全降级:** 插件自身抛异常时默认 `reject`(安全锁定模式),并记录 `guard_error` 审计日志。 ### 1.2 `session/event` - `turn/start` — 维护会话轮次序号(写入审计日志 `turnIndex`) - `user/message` — 聊天流审批兜底:检测用户回复中的「允许 / 拒绝 / 同意 / 放行 / 批准 / 可以 / allow / deny」等关键词,对最近一条待审批项做出决策 ### 1.3 `session/disposed` 清理会话状态;将该会话所有待审批项标记为拒绝。 ### 1.4 卸载(等价 PRD `plugin:unload`) 经 `ctx.effect` 注册 disposer,卸载时: 1. 所有待审批项标记 `timeout_deny` 并写入审计 2. `audit.keepAfterUnload=true` 时写入 `~/.deepseek-harness/audit/tool-guard-<时间戳>.json` 3. 清空全部状态与日志 4. 移除全部事件订阅(cordis 自动) --- ## 2. 大模型工具(guard_*) 注册在 `ctx.tools`,模型可直接调用。管理类工具默认不受拦截,但每次调用记录审计日志。 | 工具名 | 入参 | 返回 | 说明 | |---|---|---|---| | `guard_status` | 无 | `{securityLevel, paused, pausedByUser, resumeAt, activeRules[], todayBlockCount, totalChecked, totalAllowed, totalRejected, totalApproved, totalTimeout, whitelistPaths[], pendingApprovalCount, startedAt}` | 查询安全守卫状态 | | `guard_stats` | 无 | `{totalChecked, allowed, rejected, approved, timeout, todayBlockCount}` | 获取审计统计 | | `guard_recent_blocks` | `limit?: number`(1-100,默认 20) | `{items: AuditLog[]}` | 最近被拦截 / 拒绝 / 审批的记录(跨会话,按时间倒序) | | `guard_set_level` | `level: "loose" \| "standard" \| "strict"` | `{success, newLevel, error?}` | 切换安全级别(非法值由框架 schema 校验拒绝) | | `guard_pause` | `durationMinutes?: number` | `{success, resumeAt, error?}` | 暂停防护;省略时长用配置 `pause.autoResumeMinutes`(默认 10 分钟);`0` = 需手动恢复;严格级别不允许暂停 | | `guard_resume` | 无 | `{success}` | 恢复防护 | | `guard_whitelist_add` | `path: string`(绝对路径) | `{success, path}` | 向路径白名单添加目录(全局运行时生效) | | `guard_whitelist_remove` | `path: string` | `{success, path}` | 从路径白名单移除目录 | > 注:`guard_recent_blocks` 按 PRD §5.1 返回审计记录数组,为便于结构化输出以 `{items: [...]}` 包裹。 --- ## 3. HTTP 端点(客户端侧边面板数据源) 经宿主 `webServer` 服务注册(`ctx.inject(['webServer'], …)` 延迟就绪绑定,路由随服务生命周期 自动清理),同源相对路径访问。客户端文件:`src/client.js`(`package.json` 的 `dsh.client.platform: "web"` 声明,宿主 `dsh-client-modules` 拾取)。 > 审批通道说明:宿主提供 `approval` 服务(web GUI 部署)时,`approve` 决策**优先走原生审批** > (与 dsh-tools 的 serviceAsk 契约一致,审批卡在宿主 UI 弹出),不产生本表 `pending/approve` > 记录;本表面板审批仅覆盖**无 approval 服务 / 调用无 agent** 时的内置 ApprovalManager 回退路径。 | 方法 | 路径 | 入参(query) | 返回 | |---|---|---|---| | GET | `/tool-guard/status` | — | 状态快照(同 `guard_status`) | | GET | `/tool-guard/stats` | — | 审计统计(同 `guard_stats`) | | GET | `/tool-guard/recent` | `limit`、`sessionId`(可选) | `{items: AuditLog[]}` | | GET | `/tool-guard/pending` | — | `{items: PendingApproval[]}`(含 `remainingMs`) | | POST | `/tool-guard/approve` | `id`、`decision=allow\|deny\|allow-session` | `{ok}` 或 `{ok:false, error}` | | POST | `/tool-guard/pause` | `minutes`(可选) | `{success, resumeAt}` 或 400 | | POST | `/tool-guard/resume` | — | `{success}` | | POST | `/tool-guard/level` | `level=loose\|standard\|strict` | `{success, newLevel}` | | POST | `/tool-guard/rule` | `rule=dangerousCommands\|pathWhitelist\|sensitiveFiles\|writeProtection`、`enabled` | `{success, rule, enabled}` | | POST | `/tool-guard/whitelist/add` | `path` | `{success, path}` | | POST | `/tool-guard/whitelist/remove` | `path` | `{success, path}` | | POST | `/tool-guard/logs/clear` | — | `{success}` | | GET | `/tool-guard` | — | 简易状态页(HTML;WebRoute 契约要求绝对路径不带尾斜杠) | --- ## 4. 配置项(cordis.patch.yml) | 配置 key | 类型 | 默认值 | 说明 | |---|---|---|---| | `enable` | boolean | `true` | 插件总开关 | | `securityLevel` | string | `"standard"` | 安全级别:loose / standard / strict | | `rules.dangerousCommands.enabled` | boolean | `true` | 危险命令黑名单开关 | | `rules.dangerousCommands.patterns` | string[] | `[]`(= 内置列表) | 危险命令正则模式列表 | | `rules.pathWhitelist.enabled` | boolean | `true` | 路径白名单开关 | | `rules.pathWhitelist.paths` | string[] | `[]`(= 仅当前工作目录) | 允许操作的目录列表 | | `rules.sensitiveFiles.enabled` | boolean | `true` | 敏感文件黑名单开关 | | `rules.sensitiveFiles.patterns` | string[] | `[]`(= 内置列表) | 敏感文件 glob 模式列表 | | `rules.writeProtection.enabled` | boolean | `true` | 文件写入保护开关 | | `rules.writeProtection.requireApprovalForOverwrite` | boolean | `true` | 覆盖已有文件是否需审批 | | `rules.writeProtection.requireApprovalForDelete` | boolean | `true` | 删除文件是否需审批 | | `tools.shell` | string[] | `['bash','pwsh','shell','terminal']` | shell 工具名模式(command 参数) | | `tools.read` | string[] | `['read','read_image','file_read']` | 读取工具名模式(路径参数) | | `tools.write` | string[] | `['write','file_write']` | 写入工具名模式 | | `tools.edit` | string[] | `['edit','file_edit']` | 编辑工具名模式 | | `tools.delete` | string[] | `['delete','file_delete','remove']` | 删除工具名模式 | | `approval.timeoutSeconds` | number | `120` | 审批超时秒数(仅内置 ApprovalManager 回退路径;原生 approval 服务时长由宿主掌控) | | `approval.defaultOnTimeout` | string | `"deny"` | 超时默认决策:allow / deny | | `pause.autoResumeMinutes` | number | `10` | 暂停自动恢复分钟数 | | `audit.keepAfterUnload` | boolean | `false` | 卸载时是否保留审计日志(写入本地 JSON) | | `audit.maxRecordsPerSession` | number | `200` | 单会话最大日志条数(滚动覆盖) | | `audit.sensitiveFields` | string[] | 内置列表 | 审计脱敏字段名 | > 工具名模式支持 `*` 通配(如 `file_*`)。规则开关支持运行时覆盖:面板 `/tool-guard/rule` 与 HTTP 开关立即作用于所有会话。 --- ## 5. 审计日志结构(AuditLog) ```typescript interface AuditLog { id: string timestamp: number // Unix epoch 毫秒 sessionId: string turnIndex: number // 轮次序号 toolName: string args: Record // 脱敏后 decision: 'allow' | 'reject' | 'approve_allow' | 'approve_deny' | 'timeout_deny' | 'allow_session' matchedRule?: string // dangerous_command / path_whitelist / sensitive_file / write_protection / strict_shell / downstream / guard_error reason?: string } ``` --- ## 6. 审批对象结构(PendingApproval) ```typescript interface PendingApproval { id: string sessionId: string toolName: string args: Record // 脱敏后 matchedRule: string riskDescription: string requestedAt: number timeoutAt: number // Infinity 表示不超时 result: 'pending' | 'allowed' | 'denied' | 'timeout' | 'allow-session' } ``` --- ## 7. 行为约束 - **零侵入**:不修改任何 Agent 业务代码与工具入参;仅做 allow / deny / 审批决策。 - **安全优先**:规则正则异常跳过该条并记录警告;插件自身异常默认拒绝(安全锁定)。 - **审批超时**:默认 120 秒,超时默认拒绝(`defaultOnTimeout: "deny"`),宁可误杀不可漏放。 - **脱敏**:`api_key / password / token / secret / authorization / private_key / access_key / cookie / session_token` 等字段在日志与审批卡片中替换为 `[REDACTED]`(大小写不敏感、嵌套递归)。 - **暂停**:暂停期间所有调用放行但记录审计;严格级别禁止暂停。