From dd4e685f5a72d1392fd7613ccecb9556d46cbcd0 Mon Sep 17 00:00:00 2001 From: Pierre Kancir Date: Mon, 7 Sep 2026 12:53:47 +0200 Subject: [PATCH] .github: add zizmor CI check Scans .github/ for template injection, over-broad permissions, and unpinned actions/images on the same triggers as actionlint. The whole directory, not just the workflows: the composite actions under .github/actions/ carry run: blocks of their own and already trigger this job, but nothing in CI audits them -- actionlint does not shellcheck composite-action scripts. A template injection planted in save-ccache is not reported when only .github/workflows/ is scanned, and is a high finding when .github/ is. Annotate the ardupilot-dev-ros:latest image in colcon.yml and test_dds.yml: those jobs continuously test against the dev image itself, so they need to track "latest" rather than a pinned snapshot of it, and zizmor's unpinned-image check would otherwise flag that as unintentional. Co-Authored-By: Claude Opus 5 (1M context) --- .github/actionlint.yaml | 2 +- .github/workflows/colcon.yml | 5 ++++- .github/workflows/test_dds.yml | 5 ++++- .github/workflows/workflows_lint.yml | 19 +++++++++++++++++++ .github/zizmor.yml | 13 +++++++++++++ 5 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index 8e5b8270038..b923df0f1f4 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -1,5 +1,5 @@ # actionlint configuration -- https://github.com/rhysd/actionlint -# see .github/workflows/test_workflow_lint.yml for how CI invokes it +# see .github/workflows/workflows_lint.yml for how CI invokes it self-hosted-runner: # runners actionlint cannot know about; keep in sync with the runs-on: values diff --git a/.github/workflows/colcon.yml b/.github/workflows/colcon.yml index 8fd38442c9d..908d54f6ca5 100644 --- a/.github/workflows/colcon.yml +++ b/.github/workflows/colcon.yml @@ -153,7 +153,10 @@ jobs: runs-on: ubuntu-22.04 timeout-minutes: 60 container: - image: ardupilot/ardupilot-dev-ros:latest + # deliberately floating: this is the continuous-testing job for the + # ardupilot-dev-ros image itself, so it must track whatever "latest" + # points at, not a pinned snapshot of it + image: ardupilot/ardupilot-dev-ros:latest # zizmor: ignore[unpinned-images] steps: # Sparse checkout to make .github/actions/* available without polluting the colcon workspace - uses: actions/checkout@v7 diff --git a/.github/workflows/test_dds.yml b/.github/workflows/test_dds.yml index 92e51f3e24d..ed50f197858 100644 --- a/.github/workflows/test_dds.yml +++ b/.github/workflows/test_dds.yml @@ -154,7 +154,10 @@ jobs: actions: write # save-ccache prunes the previous cache entry runs-on: ubuntu-22.04 container: - image: ardupilot/ardupilot-dev-ros:latest + # deliberately floating: this is the continuous-testing job for the + # ardupilot-dev-ros image itself, so it must track whatever "latest" + # points at, not a pinned snapshot of it + image: ardupilot/ardupilot-dev-ros:latest # zizmor: ignore[unpinned-images] options: --user 1001 strategy: fail-fast: false # don't cancel if a job from the matrix fails diff --git a/.github/workflows/workflows_lint.yml b/.github/workflows/workflows_lint.yml index 276f48227f2..a0ada321d66 100644 --- a/.github/workflows/workflows_lint.yml +++ b/.github/workflows/workflows_lint.yml @@ -7,12 +7,14 @@ on: - '.github/workflows/**' - '.github/actions/**' - '.github/actionlint.yaml' + - '.github/zizmor.yml' pull_request: paths: - '.github/workflows/**' - '.github/actions/**' - '.github/actionlint.yaml' + - '.github/zizmor.yml' workflow_dispatch: @@ -47,3 +49,20 @@ jobs: shell: bash env: SHELLCHECK_OPTS: -e SC2086 + + - name: Install zizmor + run: pip install zizmor==1.30.0 + + # workflow security: template injection, over-broad permissions, + # unpinned actions and images; see .github/zizmor.yml. + # + # the whole of .github/, not just the workflows: composite actions under + # .github/actions/ carry run: blocks of their own, which nothing else in + # CI audits -- actionlint does not shellcheck them -- and dependabot.yml + # is checked too. + # + # medium and above for now. The repo has no medium findings left, so + # this gates on high; below it sit ~78 low ones, most of them checkouts + # without persist-credentials: false, left for a later pass. + - name: zizmor + run: zizmor --min-severity=medium .github/ diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 00000000000..483a407224a --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,13 @@ +# zizmor configuration -- https://docs.zizmor.sh/configuration/ +# see .github/workflows/workflows_lint.yml for how CI invokes it + +rules: + unpinned-uses: + config: + policies: + # this repo pins actions to a release tag and lets dependabot + # (.github/dependabot.yml) move them, rather than pinning to a commit + # hash. ref-pin requires a ref of some kind and accepts either a tag + # or a branch, so `@master` passes this as well; hash-pin is what would + # reject it, and nothing here asks for a tag specifically. + "*": ref-pin