[6.x] Harden GitHub Actions workflows with zizmor#14687
Merged
Conversation
Adds a 7-day cooldown before Dependabot proposes updates to GitHub Actions dependencies. This gives the community time to discover and report any supply chain compromise in a newly released version before it lands in a PR. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
zizmor flags pull_request_target as a dangerous trigger because it runs with write permissions and access to secrets, making it risky when combined with code checked out from a fork. This workflow never checks out any code — it only makes GitHub API calls using the built-in token — so the trigger is safe here. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GitHub Actions defaults to overly broad token permissions when no permissions block is defined. Each job now declares only what it needs: - code-style-lint: contents:read — only checks out and reads code - pr-title: none — only uses event context variables, no token ops - release: contents:write — creates releases and uploads assets - stale: issues:write + pull-requests:write — comments and closes stale items - tests (php/js): contents:read — checks out and runs tests, no writes - tests (slack): actions:read — reads workflow conclusion to decide whether to notify Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
actions/setup-node enables dependency caching automatically when package.json includes a packageManager or devEngines.packageManager field. A poisoned cache could silently contaminate published release artifacts. Explicitly disabling it ensures release builds always use a clean install. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
By default, actions/checkout writes the GitHub token into the local Git config so subsequent steps can push or pull. Any step after checkout — including third-party actions — can read that token. Setting persist-credentials: false removes it immediately after checkout, limiting the token's exposure to only the checkout step itself. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs zizmor on every push to master/*.x and on all PRs. Results are uploaded as SARIF and will appear in the Security tab. The workflow is intentionally added before all findings are resolved so we can see them surface in the UI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the SARIF upload approach with inline PR annotations, which surface findings directly in the diff where they're most actionable. The job will now fail on findings, enabling it to be used as a required status check to block merges. Also adds path filtering so the workflow only runs when .github/**.yml files are changed — zizmor only understands Actions syntax so there's no value in running it on unrelated changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the archived actions/create-release and actions/upload-release-asset (×4) with a single softprops/action-gh-release step that handles both release creation and asset uploads. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Uses the pre-installed gh CLI instead of a third-party action, avoiding a supply chain dependency for functionality the runner already provides. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents redundant runs queuing up when multiple commits are pushed to the same branch in quick succession. PR-triggered workflows use cancel-in-progress: true so a new push immediately cancels the prior run. The tests workflow uses a conditional so only PR runs are cancelled — scheduled nightly runs are left to complete. Release and stale workflows are suppressed instead since they trigger on tags/schedule where concurrent runs are impossible in practice. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a workflow-level `permissions: {}` block to all workflows that
were missing one, ensuring no job can accidentally inherit broad default
permissions. Moves the pull-requests.yml permission down to the job
level where it belongs. Adds explanatory comments to every non-obvious
permission so it's clear why each one is needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avoids direct template expansion of the secret into the shell script, which could allow shell metacharacters in the secret value to be interpreted as commands. Passing it as an env variable means bash treats it as data, not syntax. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gives each job an explicit human-readable display name in the GitHub Actions UI rather than falling back to the job key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This reverts commit d187405.
Job keys are already human-readable and match the required status check names in branch protection rules — adding name: fields would break those rules without adding value. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The other workflows that added a concurrency block use the pull_request trigger, where github.ref is the synthetic refs/pull/<n>/merge ref -- already unique per PR, so each PR lands in its own group. pull-requests.yml uses pull_request_target, which runs in the context of the base branch, so github.ref resolves to refs/heads/<base> instead. Every PR opened against the same base shares one group, and cancel-in-progress would cancel earlier PRs' runs. Keying the group on github.event.pull_request.number restores per-PR isolation for this workflow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
Introduces zizmor, a static analyser for GitHub Actions, and applies its recommendations to existing workflows.
Changes include:
pull_request_targettrigger in the pull requests workflow (no fork code is checked out, so the pattern is safe)persist-credentials: falseon all checkout steps to prevent the GitHub token from being exposed to subsequent steps