fix: merge project permissions.allow into tag mode --allowedTools#1173
fix: merge project permissions.allow into tag mode --allowedTools#1173qozle wants to merge 2 commits intoanthropics:mainfrom
Conversation
PR anthropics#1002 hardened tag mode by adding an explicit --allowedTools allowlist in src/modes/tag/index.ts. In acceptEdits mode with no prompt handler, any tool not in that list falls through to "ask" and is immediately denied. This inadvertently broke project .claude/settings.json permissions.allow entries — Bash patterns like Bash(pnpm test:*) that maintainers explicitly approved are now silently denied. After restoreConfigFromBase() runs, .claude/settings.json is the trusted base-branch version reviewed by a maintainer. Read its permissions.allow entries and append them to claudeArgs as an additional --allowedTools flag so that project-approved tools are respected without weakening the security hardening. Fixes anthropics#1063. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
src/entrypoints/run.ts
Outdated
| // project-approved tools (e.g. Bash(pnpm test:*)) are not silently denied. | ||
| // PR #1002 hardened tag mode with an explicit --allowedTools allowlist, which | ||
| // inadvertently stopped respecting project settings entirely. | ||
| if (modeName === "tag") { |
There was a problem hiding this comment.
This only runs when restoreBase is set (PR-triggered tag mode). Issue-triggered tag mode also has the #1002 hardening but no restore, so project permissions.allow stays ignored there. The settings file is equally trusted in that case (default branch checkout). Suggest moving this block to just after the if (restoreBase) { ... } closes, still gated on modeName === "tag".
src/entrypoints/run.ts
Outdated
| (t): t is string => typeof t === "string" && t.length > 0, | ||
| ); | ||
| if (projectTools.length > 0) { | ||
| prepareResult.claudeArgs += ` --allowedTools "${projectTools.join(",")}"`; |
There was a problem hiding this comment.
String-concatenating into claudeArgs means this goes through shell-quote parsing in base-action. A tool entry containing " or , would break. Safer to thread the project tools through to prepareTagMode's tool builder so they're added to the array before it's serialized. If that's too invasive for this PR, at minimum escape " in the joined string.
… merge Two fixes based on ashwin-ant's review of anthropics#1173: 1. Move project permissions merge outside the `if (restoreBase)` block. Issue-triggered tag mode also has the anthropics#1002 --allowedTools hardening but no config restore (default branch checkout is already trusted), so the previous placement silently skipped the merge for issue events. 2. Filter tool entries containing `"` before joining into the --allowedTools shell argument. A double-quote in a tool name would escape out of the quoted string and corrupt the args. Entries using the standard Bash(cmd:*) pattern are unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes #1063.
Problem
PR #1002 ("Harden tag mode tool permissions against prompt injection") added an explicit
--allowedToolslist to tag mode. InacceptEditsmode with no prompt handler, anything not in that list hits "ask" → immediately denied. This regression broke project.claude/settings.jsonpermissions.allowentries — tools likeBash(pnpm test:*)that maintainers explicitly approved are silently denied.Fix
restoreConfigFromBase()already runs inrun.tsbefore the CLI starts, replacing.claude/with the trusted base-branch version. After that restore, read the project's trustedpermissions.allowentries and append them toclaudeArgsas an additional--allowedToolsflag.This restores the pre-#1002 behavior of respecting project settings while keeping the hardening intact — the entries come from the base branch (maintainer-reviewed), not the PR head.
Security
No new trust surface. The project
permissions.allowentries are read from the base-branch version of.claude/settings.json(already trusted by the existing restore logic), not from the PR-authored version.