权限
一句话版:DSH 的权限体系控制 agent 能执行什么、要不要批准:一套"预设"选操作模式档,一组"批准策略"决定是否询问用户。它不是沙箱,真正的文件访问边界在 沙箱。
一、权限预设(preset)
| 预设 | 沙箱模式 | 批准策略 | 行为 |
|---|---|---|---|
workspace-write | workspace-write | ask | 只写当前工作区,写操作需批准 |
read-only | read-only | ask | 只读沙箱,操作需确认 |
danger-full-access | danger-full-access | never | 全部操作直接执行,无批准门 |
一个 preset 把 sandbox/mode 与 approval/policy 两个旋钮打包成一张表:
workspace-write(+ask)是出厂默认;read-only与danger-full-access需显式切换或配置- 会话中用
/permission切换(裸命令报告当前值,带参数切换);切换只记日志事件,且只在有效值变化时落地 - 两个旋钮拼不出任何表项时,当前态显示为
custom——只能显示、不能选中(派生态,非可选预设)
二、批准策略(approval)
真实枚举只有 ask 与 never(没有 full-access):
| 策略 | 行为 |
|---|---|
ask | 操作执行前询问用户 |
never | 不询问,直接执行(危险) |
有效策略是最后一条 approval/policy 事件(回退配置);never 在进入交互分发之前就拒绝。
三、配置
# ~/.dsh/settings.yaml
permission:
defaultPreset: danger-full-access
出厂默认
workspace-write(+ask);danger-full-access来自这里显式覆盖。
环境变量覆盖(启动时生效):
export DSH_PERMISSION_MODE=workspace-write
覆盖优先级(高 → 低):
| 层 | 说明 |
|---|---|
DSH_PERMISSION_MODE | 进程级 fallback,改写沙箱模式并推导批准策略(danger-full-access → never,否则 ask) |
permission.defaultPreset | 未来会话默认;省略时按已组合的 sandbox/approval 默认反推 |
| 出厂默认 | workspace-write(+ ask) |
关键语义:默认值只在创建会话时读取,创建会把 permission/preset、sandbox/mode、approval/policy 钉进该会话,之后的变更永不改动已存在会话;恢复的种子会话保留既有权限。preset 表是进程级的,增删预设需重载插件。
四、批准决策链(ask 到底走什么)
需要批准的操作把决策路由到 ctx.approval.request(req) 这个一次性授权缝:
| 返回 | 含义 |
|---|---|
allowed-once | 本次批准,只对该请求动作有效,不形成记忆规则 |
rejected | 拒绝 |
cancelled | 请求被中止 |
unavailable | 没有可用 answerer,fail closed(视为拒绝) |
- fail-closed:answerer 缺失或失败时按拒绝收场,不放行;
ask语义即"有 answerer 才问,没有就拒绝"。 - 授权一次性:词汇只有
allowed-once,没有allow-always、撤销或授权存储;策略只有ask/never两档。 - answerer 是
approval/request的瀑布监听器,每个部署只组合一个终点 answerer;ACP 自动化桥为它拥有的会话提供一次性机器决策。 - 审计事件
approval/asked+approval/decided仅写日志,模型只看到提问方最终工具结果;沙箱 bash 工具在升级重试时也走这条缝。
五、询问用户工具(ask_user_question)
除了"要不要批准",模型还能主动问人:ask_user_question 是挂在 ctx.userQuestions 上的模型可见工具,用于确认、二选一、或补齐缺失信息。
- 参数:
questions(非空数组,每项必填id与question,可选header、options、multi_select);推荐项放首位并在 label 追加(Recommended)。 - 返回
{ answers: [{ id, selected, custom? }] }:selected是选中的 option label,custom是自由文本——多选补充、单选覆盖。 - 约束:待答问题阻塞工具调用直到人回答;运行期被其它 agent 拥有的子代理不能问人(
DELEGATED_CALLER),须把未决问题写进自己的最终结果。
六、权限 vs 沙箱(容易混)
| 权限(permission) | 沙箱(sandbox) | |
|---|---|---|
| 管什么 | 操作的"模式档" + 批准 | 命令执行时的文件边界 |
| 层面 | preset + approval 策略 | ctx.sandbox.confine |
| 例子 | 写文件要不要批准 | 命令在 read-only 下跑 |
预设选择模式,沙箱执行边界。把 preset 设成 danger 不等于绕过沙箱:命令照样过 confine。详见 沙箱与安全。
七、最佳实践
| 场景 | 建议 |
|---|---|
| 日常使用 | workspace-write(写操作有确认,防误操作) |
| 全自动跑批/CI | 临时切 danger-full-access |
| 敏感项目 | 保持安全预设 + 配合沙箱 read-only |
| headless/无人值守 | 组合一个终点 answerer 或 ACP 机器决策,否则 ask 一律 fail closed |
权限是"预设",不是"沙箱"。真限制文件系统访问,得配合 sandbox 配置。