Skip to content

feat: add Claude-style deny-first permission overlay - #457

Open
OldKing-lion wants to merge 3 commits into
vastsa:mainfrom
OldKing-lion:feat/host-deny-rules
Open

OldKing-lion wants to merge 3 commits into
vastsa:mainfrom
OldKing-lion:feat/host-deny-rules

Conversation

@OldKing-lion

Copy link
Copy Markdown

Summary

Add a host-owned deny-first overlay so auto (YOLO) is no longer unbounded.

Permission modes stay ask / accept-edits / auto. Always-deny is not a fourth mode. A match is PermissionDecision::Deny and still wins in auto, including over session grants and scratch auto-allow.

Closes the gap with Claude Code: users can name tools, paths, and command prefixes that stay denied; policy plugins can only add rules.

See ADR 0267 / D433.

Behavior

Settings → AI → Permissions: JSON textarea under the mode select (AppSettings.permissionDeny).

{
  "tools": ["Bash", "plugin_*"],
  "paths": ["**/.env", "~/.ssh/**"],
  "commands": ["curl", "rm -rf"]
}

wxd and others added 3 commits September 16, 2026 10:57
- 用户设置与插件可贡献 tools/paths/commands glob,命中即 Deny,压过 auto、session grant、low-risk 与 accept-edits
- 插件需声明 agent.permission.deny,只能追加限制不能放宽;Plan/Goal 硬拒绝仍优先
- Settings AI 页提供 JSON 编辑,SDK 与 host 同步校验;overlay 拒绝统一返回 TOOL_DENIED
- 记录 ADR 0249 / D420,并补齐中英 spec、权限矩阵与插件开发指南
Path deny now uses the same dangling-symlink ancestor resolver as
execution, so auto cannot write through a workspace link onto a denied
target. Path arguments are trimmed, Windows extended prefixes are
stripped, and Edit MV destinations use the hashline parser.

Relative ../, command whitespace, and scratch auto-allow remain denied
under auto. Specs, ADR 0249, and permissionDeny copy are updated.

@muzimu217 muzimu217 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢这个 PR——deny-first 的定位(不是第四种模式、deny 在 auto 下仍然赢过 grants 与 scratch auto-allow)和几处实现细节都很到位:mv_dest_from_ops 复用真实 parser 防路径漂移、Windows \\?\/UNC/msys 路径处理、**/.env 对裸 .env 的 basename fallback,都是对的。ADR 0267/D433 与 spec en/zh 成对也齐。四点意见:

1.(会挡合并)缺 pt-BR locale。 当前 main 的 packages/i18n/src/locales/ 已是 9 个 locale(de/en/es/fr/ko/pt-BR/tr/zh-CN/zh-TW),本 PR 只改了 8 个、pt-BR 缺席。这个 PR 的 workflow 尚未被批准运行,键集全等的 catalog 测试还没机会拦——建议补上 pt-BR 再进入 review。

2.(安全文档补强)复合命令的绕过面值得一个显式反例。 spec 已多处写清 "string match, not argv"(en/zh 一致,很好),但"前缀匹配从命令串开头锚定"意味着 cd /tmp && rm -rf ~/x 不会命中 rm -rf*,rm -fr 变体也不会命中。deny 是安全边界,用户最容易误解的恰是这一点——建议 spec 的 deny 段补一个反例句("a rm -rf* rule does NOT stop cd /tmp && rm -rf …"),一段话的成本,能省掉未来一批"我明明禁了 rm"的 issue。

3.(可诊断性)DenyHit 的呈现。 命中时的 DenyHit{kind, pattern} 是否透传到工具错误 details / UI("被规则 X 拒绝"),还是坍缩成笼统的 TOOL_DENIED?用户排障需要知道命中的是哪条规则;若尚未透传,建议作为跟进项。

4.(合并顺序)与 #954 的设置 IA 冲突。 本 PR 与 #954(host 主导的自动权限审核)都往 SettingsPage/settings-search.ts 加权限入口且同域,两边合并顺序需要维护者先裁——建议在两个 PR 的描述里互相标注依赖关系,先定先后,后到的一方 rebase 成本会小很多。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants