anthropics / anthropics/claude-code-action
Regression: Tag mode --allowedTools overrides project .claude/settings.json permissions.allow
- Dominant language
- TypeScript
- Stars
- 8.9k
- Forks
- 2.1k
- Avg merge
- 3d 9h
- Merged PRs (30d)
- 10
Description
## Summary
After PR #1002 ("Harden tag mode tool permissions against prompt injection", merged March 12, 2026), project-level `.claude/settings.json` `permissions.allow` entries are no longer respected in tag mode.
The hardcoded `--allowedTools` list in `src/modes/tag/index.ts` combined with headless `acceptEdits` mode means any tool not in that hardcoded list falls to "ask" → no prompt handler → denied. Project settings are loaded (`settingSources` confirms `["user", "project", "local"]`), but effectively ignored.
## Example
Given a project `.claude/settings.json`:
```json
{
"permissions": {
"allow": [
"Bash(pnpm test:*)",
"Bash(pnpm fix:*)",
"Bash(node:*)"
]
}
}
```
Any `@claude` task that requires running tests hits repeated permission denials, even though these tools are explicitly allowed in the project settings.
## Root Cause
PR #1002 changed `src/modes/tag/index.ts` to:
```typescript
claudeArgs += ` --permission-mode acceptEdits --allowedTools "${tagModeTools.join(",")}"`;
```
Where `tagModeTools` is a hardcoded list of read tools + git operations + GitHub MCP tools. In headless `acceptEdits` mode, anything not in `--allowedTools` is denied with no fallback.
## Previously Working
[Issue #189](https://github.com/anthropics/claude-code-action/issues/189) was closed in June 2025 with the reporter confirming that `.claude/settings.json` permissions were being reflected in the action without any special configuration. This confirms the behavior worked before the hardening changes.
## Docs Conflict
From [Claude Code Settings](https://code.claude.com/docs/en/settings):
> **Array settings merge across scopes.** When the same array-valued setting (such as `permissions.allow`) appears in multiple scopes, the arrays are **concatenated and deduplicated**, not replaced.
The current behavior contradicts this — CLI-level `--allowedTools` effectively replaces rather than merges with project settings.
## Related
- [Issue #695](https://github.com/anthropics/claude-code-action/issues/695) — Same pattern with MCP tools: tag mode filters `userAllowedMCPTools` to only `mcp__github_*`.
## Suggested Fix
The security hardening in PR #1002 is valid. But `tagModeTools` should merge project `permissions.allow` entries rather than ignoring them. `Bash(...)` allow rules from project settings don't bypass the `git-push.sh` wrapper or grant filesystem write access outside `$GITHUB_WORKSPACE`.
Contributor guide
Research direction
Read src/modes/tag/index.ts and the changes from PR #1002 first; trace how project settings are loaded alongside the hardcoded tagModeTools list. Verify the provided .claude/settings.json example with a tag task, ensuring allowed Bash commands work while the existing security restrictions remain in place.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- devops, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100