ci: harden GitHub Actions workflows#208
Conversation
Update action version comments to reflect exact semver versions.
- Fix bot-conditions: use github.event.pull_request.user.login instead of
github.actor for dependabot check
- Fix template-injection: use GITHUB_BASE_REF env var instead of inline expression
- Fix excessive-permissions: set permissions: {} at workflow level and scope
per job in ai-labeler, labeler, release-github, release-kotlin, release-ruby,
release-typescript, sensitive-change-gate
- Suppress cache-poisoning: branch-isolated caches cannot be poisoned by fork PRs
- Suppress dangerous-triggers: pull_request_target workflows only run trusted
actions with no PR code checkout or execution
- Fix artipacked: add persist-credentials: false to all checkout steps that
do not require git push; suppress artipacked on release-go tag job which
needs credentials for git push
- Fix excessive-permissions: set permissions: {} at workflow level and scope
per job in codeql, security, test, release-swift, and smithy-verify
- Fix dependabot-cooldown: add cooldown: default-days: 10 to all ecosystem
entries in dependabot.yml
- Suppress cache-poisoning: branch-isolated npm caches in release-typescript
- Suppress superfluous-actions on softprops/action-gh-release: actions are more maintainable than inline shell code
Add lint-actions job to test.yml near the existing actionlint job to continuously audit workflow security with zizmor.
Sensitive Change Detection (shadow mode)This PR modifies control-plane files:
|
There was a problem hiding this comment.
2 issues found across 16 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/test.yml">
<violation number="1" location=".github/workflows/test.yml:21">
P2: The `lint-actions` job duplicates the actionlint step that already runs in the dedicated `actionlint` job. Every CI run will execute actionlint twice on separate runners. Remove the duplicate step from `lint-actions` so it only runs zizmor.</violation>
</file>
<file name=".github/workflows/ai-labeler.yml">
<violation number="1" location=".github/workflows/ai-labeler.yml:58">
P2: The `spec-impact` job may need `issues: write` to execute the `updateIssueComment` GraphQL mutation. PR comments are issue comments at the API level, and this mutation operates in the issues domain. Both `classify` and `breaking` jobs in this workflow include `issues: write` — its omission here looks like an oversight that could cause the "update existing comment" path to fail with a 403.</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
This PR hardens the repository’s GitHub Actions and Dependabot configuration by pinning actions, tightening permissions to least-privilege, and adding workflow static analysis (zizmor/actionlint) to CI.
Changes:
- Pin GitHub Actions to SHA hashes and disable persisted checkout credentials in most jobs.
- Shift workflow-level permissions to
permissions: {}and grant scoped job-level permissions. - Add/extend CI auditing with actionlint + zizmor; add Dependabot cooldowns and adjust Dependabot auto-merge bot condition.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/test.yml |
Adds actionlint + zizmor auditing and applies least-privilege permissions/pinned actions across CI jobs. |
.github/workflows/smithy-verify.yml |
Pins checkout/setup-java/setup-smithy actions and disables persisted checkout credentials. |
.github/workflows/sensitive-change-gate.yml |
Adds zizmor rationale for pull_request_target and moves permissions to {} + job-scoped grants. |
.github/workflows/security.yml |
Moves to job-scoped permissions and pins actions; keeps SARIF upload permissions scoped. |
.github/workflows/scorecard.yml |
Pins checkout and SARIF upload action versions. |
.github/workflows/release-typescript.yml |
Moves to workflow permissions: {}, pins actions, and disables persisted credentials for checkout. |
.github/workflows/release-swift.yml |
Moves to workflow permissions: {}, pins checkout, and disables persisted credentials for checkout. |
.github/workflows/release-ruby.yml |
Moves to workflow permissions: {}, pins actions, and disables persisted credentials for checkout. |
.github/workflows/release-kotlin.yml |
Moves to workflow permissions: {}, pins actions, and disables persisted credentials for checkout. |
.github/workflows/release-go.yml |
Pins actions and disables persisted credentials in the test job; retains credentials where git pushes are required. |
.github/workflows/release-github.yml |
Moves to workflow permissions: {}, scopes job permissions, pins actions, and disables persisted credentials for checkout. |
.github/workflows/labeler.yml |
Adds zizmor rationale for pull_request_target and moves permissions to job-level. |
.github/workflows/dependabot-auto-merge.yml |
Tightens Dependabot detection condition and pins fetch-metadata action version comment. |
.github/workflows/codeql.yml |
Moves permissions to job-level least-privilege and pins CodeQL-related actions. |
.github/workflows/ai-labeler.yml |
Adds zizmor rationale for pull_request_target, moves permissions to {} + job-scoped grants, and pins checkout. |
.github/dependabot.yml |
Adds a 10-day cooldown across ecosystems to reduce Dependabot update frequency. |
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace overly broad workflow-level permissions with deny-all `permissions: {}`
and move permissions into each job that needs them.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Defense-in-depth: verify both github.actor and github.event.pull_request.user.login are dependabot[bot]. Actor validates the current trigger, user.login validates PR origin.
Workflow-level permissions: {} (deny-all), with contents: read
granted explicitly on the smithy and test jobs. The tag job
already had its own permissions: contents: write block.
Bump gosec to v2.23.0 and output SARIF format for upload to GitHub Security tab. Adds security-events: write permission to support the upload.
Scans current checkout (--no-git) for leaked secrets using gitleaks v8.22.0, installed via Go for integrity verification through the module proxy and checksum database.
Runs on pull requests only, advisory mode (continue-on-error) since it requires GitHub Advanced Security which may not be available on all plans.
bump-version.sh and sync-api-version.sh are release-critical control-plane scripts that should trigger review comments on PRs.
Allows low-risk patches through faster (2 days) while giving major bumps more soak time (7 days). Applied to all 10 ecosystem entries.
Runs actionlint and zizmor locally, gated by command-availability checks with install instructions. Wired into the check meta-target so workflow issues are caught alongside other checks.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
.github/workflows/security.yml:316
actions/dependency-review-actiontypically requirespull-requests: read(in addition tocontents: read) to fetch the PR diff/dependency changes via the API. With workflow-levelpermissions: {}and onlycontents: readhere, this job is likely to error or produce no results; addpull-requests: readto this job’s permissions.
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
continue-on-error: true # Requires GitHub Advanced Security
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0
.github/workflows/test.yml:306
- The
golangci/golangci-lint-actionstep pins the action itself, butwith: version: latestmakes the downloaded golangci-lint binary non-deterministic over time and can undermine the workflow hardening goal. Consider pinningversionto a specific golangci-lint release (or otherwise making the tool version reproducible).
- name: golangci-lint
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
with:
working-directory: go
version: latest
args: --config .golangci.yml
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
1 issue found across 6 files (changes from recent commits).
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/security.yml">
<violation number="1" location=".github/workflows/security.yml:135">
P2: The SARIF file is written under `go/` due to the job’s working directory, but the upload step points to the repo root. This will skip uploading gosec results. Use the path under `go/`.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
gosec: Revert to v2.22.4 — v2.23.0 introduced G703/G704 taint analysis rules that are false positives for an HTTP client SDK. Fix SARIF upload path to go/gosec-results.sarif to account for the job's working-directory. Dependabot: Remove semver-granular cooldown keys from the github-actions ecosystem entry — they are not supported for that package ecosystem.
The semver-specific cooldown keys are only unsupported for the github-actions ecosystem. Restore them for the other 9 entries (gomod, gradle, npm, bundler) where they are valid.
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
v2.23.0 adds G703 (path traversal) and G704 (SSRF) taint analysis rules. Both are architectural false positives for an HTTP client SDK: URL construction from caller-provided parameters and file cache paths from caller-configured directories are core functionality, not vulnerabilities. Exclude at the CLI level rather than sprinkling #nosec across 22 call sites.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace the workflow-level -exclude=G703,G704 flag with targeted #nosec annotations at each of the 22 call sites. This preserves taint analysis coverage for future code while suppressing the known false positives: - G704 (SSRF): 7 httpClient.Do() calls — an HTTP client SDK constructs URLs from caller-provided parameters by design - G703 (path traversal): 15 file operations on caller-configured cache and credentials directories Also switch gitleaks from go install (which panics with wasm error in go-re2) to a pre-built release binary with SHA256 checksum verification.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
permissions: {}at workflow levelTest plan
zizmor .Summary by cubic
Hardens all GitHub Actions workflows by pinning actions to commit SHAs, enforcing deny‑all permissions by default, and consolidating security linting. Reduces supply‑chain risk and resolves all current
zizmorfindings.New Features
lint-actionsjob intest.ymlthat runsactionlintandzizmor; removed the duplicateactionlintjob.Refactors
actions/checkout,actions/setup-*,github/codeql-action,gradle/actions/setup-gradle,ruby/setup-ruby,golangci/golangci-lint-action,actions/cache,softprops/action-gh-release) to exact SHAs with version comments.permissions: {}at the workflow level and granted minimal per‑job permissions; addedpersist-credentials: falseto allactions/checkoutsteps unless a push is required.github.event.pull_request.user.loginfor Dependabot checks, replace inline base ref expression withGITHUB_BASE_REF, add safepull_request_targetnotes, and document justifiedzizmorignores (e.g., cache isolation, release actions).cooldownfor all ecosystems to reduce update churn.Written for commit 7b3da82. Summary will update on new commits.