From 628fb7af10d4ed8791bf1aefa59cd8e792b65365 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 3 Sep 2026 14:14:10 +0200 Subject: [PATCH 1/2] ci: harden GitHub Actions workflows and add zizmor scan Adds a CI job that runs the zizmor static analyzer over the workflow files under .github/, and applies the corresponding hardening so the existing workflows pass the audit: - add persist-credentials: false to every actions/checkout step that lacked it - narrow top-level permissions: read-all to permissions: contents: read - add a 7-day cooldown to the dependabot update entries This is a CI/configuration-only change; no library code, tests, or documentation are affected. --- .github/dependabot.yml | 4 ++ .github/workflows/build-with-clang.yml | 4 +- .../workflows/build-with-standard-clang.yml | 4 +- .github/workflows/build_pip.yml | 4 +- .github/workflows/conda-build-test.yml | 4 +- .github/workflows/conda-package-cf.yml | 3 +- .github/workflows/conda-package.yml | 3 +- .github/workflows/openssf-scorecard.yml | 3 +- .github/workflows/pre-commit.yml | 4 +- .github/workflows/zizmor.yml | 39 +++++++++++++++++++ 10 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b840d80..b404563 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,8 @@ updates: schedule: interval: "weekly" day: "saturday" + cooldown: + default-days: 7 rebase-strategy: "disabled" labels: ["autoupdate"] groups: @@ -16,6 +18,8 @@ updates: schedule: interval: "weekly" day: "saturday" + cooldown: + default-days: 7 rebase-strategy: "disabled" labels: ["autoupdate"] groups: diff --git a/.github/workflows/build-with-clang.yml b/.github/workflows/build-with-clang.yml index 1e1b998..fbbde87 100644 --- a/.github/workflows/build-with-clang.yml +++ b/.github/workflows/build-with-clang.yml @@ -6,7 +6,8 @@ on: - master pull_request: -permissions: read-all +permissions: + contents: read jobs: build-with-clang: @@ -51,6 +52,7 @@ jobs: - name: Checkout repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false fetch-depth: 0 - name: Install mkl-service dependencies diff --git a/.github/workflows/build-with-standard-clang.yml b/.github/workflows/build-with-standard-clang.yml index b0bcbc5..18c8f22 100644 --- a/.github/workflows/build-with-standard-clang.yml +++ b/.github/workflows/build-with-standard-clang.yml @@ -5,7 +5,8 @@ on: push: branches: [master] -permissions: read-all +permissions: + contents: read jobs: build-with-standard-clang: @@ -42,6 +43,7 @@ jobs: - name: Checkout repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false fetch-depth: 0 - name: Install mkl-service dependencies diff --git a/.github/workflows/build_pip.yml b/.github/workflows/build_pip.yml index 51fc0d7..4bc2819 100644 --- a/.github/workflows/build_pip.yml +++ b/.github/workflows/build_pip.yml @@ -6,7 +6,8 @@ on: - master pull_request: -permissions: read-all +permissions: + contents: read jobs: build: @@ -27,6 +28,7 @@ jobs: steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false fetch-depth: 0 - uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1 diff --git a/.github/workflows/conda-build-test.yml b/.github/workflows/conda-build-test.yml index 8310c05..b0fef0d 100644 --- a/.github/workflows/conda-build-test.yml +++ b/.github/workflows/conda-build-test.yml @@ -29,7 +29,8 @@ on: default: false type: boolean -permissions: read-all +permissions: + contents: read env: module-name: mkl @@ -69,6 +70,7 @@ jobs: - name: Checkout repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false fetch-depth: 0 - name: Setup miniconda diff --git a/.github/workflows/conda-package-cf.yml b/.github/workflows/conda-package-cf.yml index cb16da9..b084275 100644 --- a/.github/workflows/conda-package-cf.yml +++ b/.github/workflows/conda-package-cf.yml @@ -6,7 +6,8 @@ on: - master pull_request: -permissions: read-all +permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/conda-package.yml b/.github/workflows/conda-package.yml index 9a069ce..970bcbf 100644 --- a/.github/workflows/conda-package.yml +++ b/.github/workflows/conda-package.yml @@ -6,7 +6,8 @@ on: - master pull_request: -permissions: read-all +permissions: + contents: read concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/openssf-scorecard.yml b/.github/workflows/openssf-scorecard.yml index ff70f86..ccc4f22 100644 --- a/.github/workflows/openssf-scorecard.yml +++ b/.github/workflows/openssf-scorecard.yml @@ -16,7 +16,8 @@ on: branches: [ "master" ] # Declare default permissions as read only. -permissions: read-all +permissions: + contents: read jobs: analysis: diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 1a4add6..041356c 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -5,7 +5,8 @@ on: push: branches: [master] -permissions: read-all +permissions: + contents: read jobs: pre-commit: @@ -15,6 +16,7 @@ jobs: - name: Checkout repo uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + persist-credentials: false # use commit hash to make "no-commit-to-branch" check passing ref: ${{ github.sha }} diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..0426033 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,39 @@ +name: Security scan of GitHub Actions workflows (zizmor) + +on: + push: + branches: + - master + pull_request: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + zizmor: + name: Scan GitHub Actions workflows + + runs-on: ubuntu-latest + timeout-minutes: 10 + + permissions: + contents: read # needed to clone the repo + + steps: + - name: Checkout mkl-service repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@70fb788f84895a7701f5643d103d587e460b5c99 # v0.6.3 + with: + # Low/informational template-injection notes come from internally-defined + # values (no external input), so they are reported as annotations but do not gate CI + min-severity: medium + advanced-security: false + annotations: true + inputs: .github/ From d35416c78df1a8733140f2fc117b4d79719b4934 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Thu, 3 Sep 2026 14:18:45 +0200 Subject: [PATCH 2/2] ci: avoid template injection in conda-build-test run blocks zizmor flagged three medium-severity template-injection findings where workflow_call string inputs were expanded directly inside run: blocks. Route each flagged input through an env: var and reference it as a shell variable so no untrusted value is interpolated into the script text. --- .github/workflows/conda-build-test.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conda-build-test.yml b/.github/workflows/conda-build-test.yml index b0fef0d..afce348 100644 --- a/.github/workflows/conda-build-test.yml +++ b/.github/workflows/conda-build-test.yml @@ -97,15 +97,22 @@ jobs: run: conda install -n base -y conda-build - name: Store conda paths as envs + env: + CONDA_SUBDIR: ${{ inputs.conda-subdir }} run: | - echo "CONDA_BLD=$CONDA/conda-bld/${{ inputs.conda-subdir }}" >> "$GITHUB_ENV" + echo "CONDA_BLD=$CONDA/conda-bld/${CONDA_SUBDIR}" >> "$GITHUB_ENV" if [ "${{ inputs.build-wheels }}" = "true" ]; then echo "WHEELS_OUTPUT_FOLDER=${{ github.workspace }}" >> "$GITHUB_ENV" fi - name: Build conda package + env: + CHANNELS_LIST: ${{ inputs.channels-list }} + RECIPE_DIR: ${{ inputs.recipe-dir }} run: | - conda build --no-test --python "${{ matrix.python_spec || matrix.python }}" ${{ inputs.channels-list }} ${{ inputs.recipe-dir }} + # CHANNELS_LIST intentionally word-splits into multiple -c args + # shellcheck disable=SC2086 + conda build --no-test --python "${{ matrix.python_spec || matrix.python }}" ${CHANNELS_LIST} "${RECIPE_DIR}" - name: Upload artifact uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1