Conversation
Move PR number from ${{ }} interpolation to env vars, switch from
inline response to response-file for model output, and add structured
JSON output schema to the classifier prompt so label extraction no
longer depends on parsing free-text model responses.
- Replace $GITHUB_ENV heredoc injection vector with file-based changelog passed through step outputs and env vars - Replace secrets:inherit with explicit secret passthrough to security.yml - Move ref_name, run_id, and git config tokens out of shell interpolation into env vars - Narrow permissions from workflow-level to per-job - Add secrets declaration to security.yml for workflow_call
Replace ${{ steps.app-token.outputs.token }} in git config run commands
with env var references across all 7 jobs to prevent token exposure
through shell interpolation.
Contributor
There was a problem hiding this comment.
3 issues found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name=".github/workflows/release.yml">
<violation number="1" location=".github/workflows/release.yml:280">
P1: `RELEASE_CHANGELOG` is no longer set when the AI changelog step fails or produces no file. GoReleaser templates use `missingkey=error`, so accessing `.Env.RELEASE_CHANGELOG` when the variable is unset will fail the release. The old code had an `else` branch that set the variable to empty — add an unconditional default export before the conditional.</violation>
</file>
<file name=".github/workflows/ai-labeler.yml">
<violation number="1" location=".github/workflows/ai-labeler.yml:85">
P1: When jq succeeds (structured JSON path), the label is not lowercased or whitespace-stripped, so a model response like `{"label": "Bug"}` won't match the `case` branches and the label is silently skipped. The `tr` normalization only runs in the fallback (jq-failure) path due to `||` precedence.</violation>
</file>
<file name=".github/prompts/classify-pr.prompt.yml">
<violation number="1" location=".github/prompts/classify-pr.prompt.yml:38">
P1: `maxCompletionTokens: 10` is too tight for the new JSON response format. A single-word response like `bug` needed ~2 tokens; `{"label": "documentation"}` needs ~7-10. If the budget is exhausted mid-object, the structured-output response is truncated and the downstream step will fail to parse it. Bump to ~25 to leave headroom.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Pull request overview
Hardens GitHub Actions workflows against script/workflow-command injection by reducing ${{ }} interpolation inside shell, switching to response-file/JSON parsing for AI outputs, and tightening secrets/permissions handling.
Changes:
- Move sensitive values (tokens, PR numbers, ref/run IDs) into
env:and reference them in shell to avoid runner-time interpolation. - Switch AI labeler to structured JSON output via response files + JSON schema.
- Replace
$GITHUB_ENVchangelog injection with a file/output-based flow and split GoReleaser install vs run.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/test.yml | Avoid direct ${{ }} interpolation in git config command by using env vars. |
| .github/workflows/security.yml | Declare workflow_call secret input and avoid interpolation in git config. |
| .github/workflows/release.yml | Remove workflow-level permissions, pass secrets explicitly, harden changelog + ref/run interpolation, and adjust GoReleaser invocation. |
| .github/workflows/ai-labeler.yml | Use PR number via env, parse model output from response-file (JSON-first), avoid direct ${{ }} in shell. |
| .github/prompts/classify-pr.prompt.yml | Require JSON output and add a strict JSON schema response format for classification. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ssions, and changelog default - Split label extraction into two lines so tr normalization always runs - Standardize responseFormat to match detect-breaking.prompt.yml shape - Bump maxCompletionTokens from 10 to 25 for JSON output headroom - Restore top-level permissions so reusable security workflow gets security-events:write - Default RELEASE_CHANGELOG to empty string so GoReleaser template doesn't fail on missing key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Context
Security audit of GitHub Actions workflows identified script injection vectors where
${{ }}expressions are interpolated by the Actions runner before bash executes. This PR eliminates all identified injection paths.Summary by cubic
Hardens GitHub Actions to prevent script and token injection across labeler, release, test, and security workflows. Uses response files with strict JSON, env vars, and least-privilege permissions.
Bug Fixes
Refactors
Written for commit 79f1b1e. Summary will update on new commits.