Skip to content

fix(ci): GitHub Actions security hardening#159

Open
stevebeattie wants to merge 4 commits into
chainguard-dev:mainfrom
stevebeattie:security/psec-923-ghaudit
Open

fix(ci): GitHub Actions security hardening#159
stevebeattie wants to merge 4 commits into
chainguard-dev:mainfrom
stevebeattie:security/psec-923-ghaudit

Conversation

@stevebeattie

Copy link
Copy Markdown
Member

Automated GitHub Actions security hardening (zizmor + actionlint + shellcheck,
plus manual review). Four focused, workflow-config-only changes — no
application code is touched.

Changes

  • Scope down checkout credentialspersist-credentials: false on the
    presubmit-testing.yaml checkout. The job passes its token explicitly to the
    steps that need it, so leaving the checkout token in .git/config for later
    steps is unnecessary exposure.

  • Move template expressions into env${{ … }} interpolations in
    presubmit-testing.yaml run: blocks are hoisted into quoted env: aliases
    (built-ins use the $GITHUB_* variables). This removes the shell
    script-injection surface created by expanding expressions directly into
    inline scripts.

  • Stop the required "Action lint" check from being un-runnable
    actionlint.yaml gated its triggers on a paths: filter, but its
    "Action lint" status check is required by branch protection on main. A
    PR that touches no workflow files would never trigger it, so the required
    check would sit permanently pending and block merge. Removing the paths:
    filter so the check runs on every PR (fail-closed).

  • Add a zizmor config + dependabot cooldown — a .github/zizmor.yml that
    disables a few cosmetic pedantic rules, and a 3-day cooldown on each
    dependabot ecosystem so brand-new (and potentially compromised) dependency
    releases aren't pulled the instant they ship.

Note for reviewer

This PR is from a fork. Because patch 0002 makes the "Action lint" check run
on all PRs, it will now run on this PR too (intended). Any OIDC / octo-sts
steps in the privileged workflows that depend on repository-scoped identity may
report as failed or skipped in a fork PR for environmental reasons unrelated to
these changes.

Refs: PSEC-923

Add .github/zizmor.yml disabling the cosmetic pedantic rules
(anonymous-definition, undocumented-permissions, concurrency-limits)
and setting the dependabot-cooldown threshold to 3 days. Add the
companion cooldown.default-days: 3 to each ecosystem in
.github/dependabot.yaml so the threshold is met. Extend the zizmor
workflow paths: filter so edits to the config and dependabot files
re-run the check.

Refs: PSEC-923
Generated-By: claude-guard chain dd432b57ed51d834e2b8f28bb26ba66d
Skills-Applied: zizmor-config
Skills-Sha: 7dedf1fc9723c0487e7d2b10722852cb5bf2a1835d1e4bb0a462bcc4d3c65a6f
Image-Sha: sha256:20335121a95cc1ec4a70b7a8f9327bf74c23563767143377c640546e0a0e2390
The action-lint job publishes the "Action lint" status check, which
is a required check on the main branch (per run-facts required_checks
with protection_visible=true). A paths: filter that gates a required
check lets a PR touching only non-workflow files skip the check and
wedge merge. Remove the paths: filter so the workflow runs on all PRs.

Refs: PSEC-923
Generated-By: claude-guard chain dd432b57ed51d834e2b8f28bb26ba66d
Skills-Applied: actionlint-config
Skills-Sha: 7dedf1fc9723c0487e7d2b10722852cb5bf2a1835d1e4bb0a462bcc4d3c65a6f
Image-Sha: sha256:20335121a95cc1ec4a70b7a8f9327bf74c23563767143377c640546e0a0e2390
The three repo-check steps interpolate ${{ github.repository_owner }}
and ${{ github.event.repository.name }} directly into run: shell
bodies, so a crafted value could execute as code under the runner.
Move github.event.repository.name into a REPO_NAME env: alias and use
the built-in $GITHUB_REPOSITORY_OWNER for github.repository_owner,
referencing both as double-quoted shell variables.

Refs: PSEC-923
Generated-By: claude-guard chain dd432b57ed51d834e2b8f28bb26ba66d
Skills-Applied: template-injection
Skills-Sha: 7dedf1fc9723c0487e7d2b10722852cb5bf2a1835d1e4bb0a462bcc4d3c65a6f
Image-Sha: sha256:20335121a95cc1ec4a70b7a8f9327bf74c23563767143377c640546e0a0e2390
The actions/checkout step did not set persist-credentials, so the
GITHUB_TOKEN credential was left in the local git config. No
downstream step performs git writes (the repo checks use the octo-sts
token via GH_TOKEN/GITHUB_TOKEN for GitHub API calls, not git), so the
safe default persist-credentials: false applies.

Refs: PSEC-923
Generated-By: claude-guard chain dd432b57ed51d834e2b8f28bb26ba66d
Skills-Applied: artipacked
Skills-Sha: 7dedf1fc9723c0487e7d2b10722852cb5bf2a1835d1e4bb0a462bcc4d3c65a6f
Image-Sha: sha256:20335121a95cc1ec4a70b7a8f9327bf74c23563767143377c640546e0a0e2390
@stevebeattie stevebeattie requested review from egibs and eslerm June 25, 2026 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant