Skip to content

ci: harden GitHub Actions security - #1

Merged
kratsg merged 3 commits into
mainfrom
secure-ci
Aug 13, 2026
Merged

ci: harden GitHub Actions security#1
kratsg merged 3 commits into
mainfrom
secure-ci

Conversation

@kratsg

@kratsg kratsg commented Aug 13, 2026

Copy link
Copy Markdown
Member

Summary

CI-security hardening only; no source, Dockerfile, or image-build logic changed.

  • Pin all third-party GitHub Actions to exact commit SHAs (via actions-up), each with a version comment:
    • actions/checkout, docker/setup-qemu-action, docker/setup-buildx-action, docker/login-action, docker/metadata-action, docker/build-push-action
  • Set persist-credentials: false on the reusable workflow's checkout step (zizmor artipacked) — it only pushes container images, never git refs.
  • Add explicit permissions: {} at the top of every workflow, so each job opts into only the permissions it needs, and document the contents/packages job permissions inline (zizmor excessive-permissions, undocumented-permissions).
  • Replace secrets: inherit with an explicit secrets map in each caller workflow, scoped to the four registry credentials the reusable workflow actually declares (zizmor secrets-inherit).
  • Name the previously anonymous docker and prepare jobs (zizmor anonymous-definition).
  • Add .github/dependabot.yml for the github-actions ecosystem: monthly grouped updates, 7-day cooldown.

Major version changes

actions-up bumped every pinned action by at least one major version (all were already on outdated majors):

  • actions/checkout v4.2.2 → v7.0.1
  • docker/setup-qemu-action v3.6.0 → v4.2.0
  • docker/setup-buildx-action v3.10.0 → v4.2.0
  • docker/login-action v3.4.0 → v4.6.0
  • docker/metadata-action v5.7.0 → v6.2.0
  • docker/build-push-action v6.15.0 → v7.3.0

These are build/push-only actions with no functional CLI usage that changed in this workflow (no changed inputs used here), so no held-back items were needed.

Held-back items

None. Nothing broke, and no repo-specific code needed to move to a different version.

zizmor ignores

  • dangerous-triggers for .github/workflows/analysisbase-dask-uc.yml (.github/zizmor.yml): this workflow's workflow_run trigger is scoped to branches: [main] and only reacts to completed runs of "Build analysis-dask-base". A fork pull_request cannot forge a workflow_run event that reports having run on main, and the upstream workflow never pushes on non-push events, so the cascading base→derived image rebuild is not exploitable the way zizmor's general heuristic assumes. This is documented with a comment in .github/zizmor.yml.

Verification

  • uvx zizmor --persona=pedantic .github → no findings (1 documented ignore)
  • No .pre-commit-config.yaml exists in this repo, so prek was not applicable
  • No pyproject.toml/pixi.toml exists, so no uv/pixi cooldown was added
  • grep -rn "uses:" .github/workflows/ shows every external action pinned to a 40-char SHA; the only non-SHA uses: lines are local ./.github/workflows/_build-and-push.yml references

🤖 Generated with Claude Code

kratsg added 3 commits August 13, 2026 13:12
Replace tag refs with exact commit SHAs (via actions-up) for
actions/checkout, docker/setup-qemu-action, docker/setup-buildx-action,
docker/login-action, docker/metadata-action, and docker/build-push-action,
each annotated with a version comment.

Assisted-by: Claude (Anthropic)
Fix zizmor pedantic findings:
- set persist-credentials: false on the reusable workflow checkout step
  (artipacked); it never pushes to the git repo, only to container registries
- add an explicit permissions: {} at workflow level in every workflow, so
  jobs must opt into the permissions they actually use
- document the contents/packages job permissions inline (undocumented-permissions)
- replace secrets: inherit with an explicit secrets map in each caller
  workflow, limited to the four registry credentials the reusable workflow
  declares (secrets-inherit)
- name the previously anonymous docker and prepare jobs (anonymous-definition)
- add .github/zizmor.yml to document and scope the one accepted finding:
  workflow_run in analysisbase-dask-uc.yml, which is restricted to branches:
  [main] and cannot be forged by a fork pull_request

Assisted-by: Claude (Anthropic)
Add .github/dependabot.yml with a monthly grouped update schedule and a
7-day cooldown for the github-actions ecosystem, so pinned action SHAs get
kept current automatically. No pre-commit config exists in this repo, so no
pre-commit ecosystem entry is needed.

Assisted-by: Claude (Anthropic)
@kratsg
kratsg marked this pull request as ready for review August 13, 2026 18:33
@kratsg
kratsg merged commit 4328906 into main Aug 13, 2026
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