一、要解决的问题

安全,dsh 原生只有二元审批(ask/never 全局策略)+ sandbox 模式,缺一层「细粒度、可分层配置的 allow/deny/ask 规则」。本插件补的就是这一层,并按 skill(tool-permission-system)把五层体系在 dsh 上重建。

二、参考模型:Claude Code 的 5 层工具安全体系

第 1 层「判断工具前是否有强行拦截……优先级最高,通常把最危险的事情进行强行拦截」PreToolUse hook
第 2 层「判断某操作是否被明确禁止」settings.json 的 deny,三级规则来源
第 3 层「判断当前的安全模式……全局的总开关」bypassPermissions 等模式
第 4 层「判断工具是否在 setting 里的 allow 白名单」permissions.allow
第 5 层「工具自身的安全属性……在定义工具的时候就确定了」isReadOnly / isDestructive / isConcurrencySafe

三、五层体系在 dsh 上的落地对照

dsh 的工具执行流水线是 tools/pre-execute(可扩展的允许/拒绝/询问门禁)→ guard → execute → post-execute。本插件把五层判断压进 tools/pre-execute 一个监听器里,产出 dsh 的 PreToolDecision(allow / deny / ask)。逐层对照:

第 1 层 强行拦截(hook)暂不复刻(dsh 已有独立 hooks 包,避免重叠);其职责由本插件的 safety 黑名单承担一部分v1 非目标
第 2 层 明确禁止(deny)decide() 流水线第 1 步:命中 deny → 拒见下
第 2 层 分层规则来源复用 dsh 的 ctx.settings 分层解析(policy→user→project→local),注册 tool-permission namespace,allow/deny/ask 三个规则数组「本地级 > 项目级 > 用户层级」同构,并在其上多一层企业 policy
第 3 层 安全模式dsh 原生 sandbox/approval 模式;本插件默认行为 defaultBehavior(passthrough/deny/ask)对齐"未命中时的模式"复用宿主
第 4 层 allow 白名单decide() 流水线第 4 步:命中 allow → 放行见下
第 5 层 工具自身属性dsh 的 defineTool 已内建 isConcurrencySafe 等;本插件不重复复用宿主
Auto Mode + 熔断v1 非目标(YAGNI);ask 直接交 dsh 的 ctx.approval,不引入 AI 分类器后续可加

决策流水线:顺序即安全

decide() 按固定顺序判决,顺序本身就是安全策略:

1. deny 命中    → 拒绝        ← 最高优先:企业层 deny 不可被下层 allow 翻案
2. ask 命中     → 弹确认框
3. safety 命中  → 强制弹确认   ← 硬编码黑名单,命中后即使配了 allow 也拦不住
4. allow 命中   → 放行
5. 默认         → defaultBehavior(passthrough 交回 dsh / deny / ask)
  • deny 在 allow 之前:「本地级 > 项目级 > 用户层级」的分层覆盖——各层同名数组 union 后,deny 恒胜,企业管理员的禁令不会被用户的 allow 翻案。

  • safety 在 allow 之前: 第 1 层「把最危险的事情进行强行拦截」精神的延续——一份硬编码危险黑名单(.git/hooks、.bashrc/.zshrc、.claude/、.dsh/、.mcp.json、rm -rf 等),命中一律强制 ask,配了 allow 也拦不住。堵的是两类:代码执行(改 shell 启动脚本/hook)与自我提权(AI 借"正常编辑文件"改自己的护栏)。

规则格式与跨平台

规则沿用课/Claude Code 的 ToolName 或 ToolName(content) 形态:

tool-permission:
  allow: [read, bash(git:*), bash(pnpm:*)]   # 只读/安全命令自动放行
  deny:  [bash(rm:*)]                         # 危险命令直接拒
  ask:   [bash(curl:*), write]               # 敏感操作弹确认

内容匹配:shell 工具走命令前缀(bash(git:*) 命中 git 开头),fs 工具走路径 glob(edit(/etc/**))。

一条贯穿的铁律:fail-closed

授权是安全边界,拉不到权限 / 规则损坏 / 无应答者时一律拒,绝不"拿不准就放行"。唯一例外是纯便利性的规则读取降级(降到 defaultBehavior + 告警),但 safety 黑名单永远运行、不可降级。

四、应用方案

同一决策内核,换"规则来源"覆盖两类场景:

A. 命令级权限管控(本插件):管 dsh 自带工具(bash/read/edit…),规则读本地 settings.yml,纯离线、不依赖任何后端。真正有价值;交互式使用下 dsh 原生 ask/never + sandbox 已够,增量主要是细粒度规则 + safety 黑名单。

B. 业务功能级权限管控(配套 demo):管自研业务工具(查天气/订票/退款…),规则来源可切换——static(身份→工具白名单写本地配置,离线)/ api(调后端权限服务,超时/不可达 fail-closed)。通用 Agent 注册全量业务工具,但每个用户按身份拿到授权子集,清单外功能一律禁。面向多租户/多角色业务 Agent。

五、安装与使用

# 体验者:拿到 tgz 后
dsh plugin --profile web add ./dsh-tool-permission-0.1.0.tgz
# 重启 dsh web,在 ~/.dsh/settings.yml 配置 tool-permission 规则

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐