fix(ci): allow jq in issue-labeler assign-label step - #1367
Conversation
The assign-label step's tool allowlist only permitted `gh`, so any `gh ... | jq ...` pipe the agent tried got denied — burning turns on retries and sometimes leaving the issue with no label at all. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ailures Address code review feedback on the jq allowlist fix: - Extend Bash(jq:*) to Steps 1 and 2 as well, so all three claude-code-action steps have consistent tool access instead of leaving two of three still degraded. - Add Read,Grep,Glob to Step 3 to match Steps 1/2, since the sparse checkout includes .github/.claude and the agent may reasonably try to inspect local files. - Turn Step 4's silent "no labels found" log line into a `::warning::` annotation so a repeat of #1361 (assign-label reporting success but applying nothing) surfaces in the run summary instead of disappearing. Note: whether jq alone fully resolves the original denials is still unverified — Claude Code's Bash permission engine denies command substitution (`$(...)`) outright regardless of allowlist, which is a plausible alternate cause. Confirming that requires a live run with show_full_output: true, which wasn't done here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…n opened issues Address second round of review feedback: - Bash(jq:*) was a mistake: standalone jq can dump the whole process environment (`jq -n env`) and read arbitrary local files (`--rawfile`, `-R`), and Steps 1-3 process fully attacker-controlled issue/comment content with allowed_non_write_users: '*'. Combined with Bash(gh:*) (which can post comments), that's a prompt-injection path to exfiltrate ANTHROPIC_API_KEY out of the process environment. None of the three skills' documented flows use standalone jq anyway (identify-security-vuln-discussion and code-of-conduct-check use no jq at all; assign-label only uses gh's own --jq flag) — this was guesswork addressing an unverified failure, not a real requirement. - Removed Bash(jq:*) from all three steps and added an explicit prompt line telling the agent to use gh's built-in --jq instead of piping to a separate jq process. This also sidesteps the original permission-denial theory by construction: a single `gh ... --jq` call never crosses a pipe boundary, so it can't hit the Bash-permission-checks-each-pipeline-segment issue in the first place, regardless of whether that was the real cause of #1361's denials. - The zero-labels warning only fires when an issue ends with no labels at all, which misses #1361-style cases where template labels are present but Step 3 added nothing on top. Added a same-set comparison (pre vs. post Step 3) scoped to newly-opened issues, which is the case where "no change" is most likely a silent failure rather than a legitimate conservative decision. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Code ReviewScope: one file changed ( No blocking bugs. Four things worth a look before merge: 1. The PR title, description, and test plan no longer describe this branchThe stated change — "widens the allowlist to
The test plan checkbox ("confirm Step 3 completes with 2. Dropping
|
Summary
Step 3 — Assign labeljob inclaude-issue-labeler.ymlrestricts tool use toBash(gh:*), so anygh ... | jq ...pipe the agent tries gets denied.Bash(gh:*),Bash(jq:*),Skill(assign-label)so filteringghJSON output throughjqno longer gets blocked.Test plan
Step 3 — Assign labelcompletes withpermission_denials_count: 0and the issue receives the expected labels.