From 0b4a206b4068b9d4ce8db925f5b20f6773af53a3 Mon Sep 17 00:00:00 2001 From: Chen Zhang Date: Mon, 22 Jun 2026 11:37:43 -0400 Subject: [PATCH 1/2] security: pin third-party GitHub Actions to commit SHAs + least-privilege permissions Pin all third-party actions to full 40-char commit SHAs (version comments retained) and add a top-level least-privilege 'permissions: contents: read' block to pure-CI workflows. dtolnay/rust-toolchain gains an explicit 'toolchain: stable' input so the SHA pin preserves channel selection. From the 2026-06-22 workspace GitHub Actions security audit. Assisted-With: Claude Opus 4.8 --- .github/workflows/copilot-setup-steps.yml | 3 +++ .github/workflows/test_and_deploy.yaml | 22 +++++++++++----------- .github/workflows/update-lockfiles.yml | 4 ++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 38cdd1b..291daba 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -11,6 +11,9 @@ on: paths: - .github/workflows/copilot-setup-steps.yml +permissions: + contents: read + jobs: # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. copilot-setup-steps: diff --git a/.github/workflows/test_and_deploy.yaml b/.github/workflows/test_and_deploy.yaml index 8a69c99..6f86fb5 100644 --- a/.github/workflows/test_and_deploy.yaml +++ b/.github/workflows/test_and_deploy.yaml @@ -28,7 +28,7 @@ jobs: fetch-tags: true - name: Setup pixi - uses: prefix-dev/setup-pixi@v0.9.6 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: manifest-path: pyproject.toml # Workaround: Dynamic versioning (versioningit) causes lock file version mismatch. @@ -46,7 +46,7 @@ jobs: run: pixi run test - name: Upload coverage to codecov - uses: codecov/codecov-action@v7 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 if: github.actor != 'dependabot[bot]' with: token: ${{ secrets.CODECOV_TOKEN }} @@ -70,7 +70,7 @@ jobs: fetch-tags: true - name: Setup pixi - uses: prefix-dev/setup-pixi@v0.9.6 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: manifest-path: pyproject.toml # Workaround: Dynamic versioning (versioningit) causes lock file version mismatch. @@ -94,13 +94,13 @@ jobs: # installed (and micromamba on PATH); pkg-install sets both up. - name: Install built conda package id: install - uses: neutrons/conda-actions/pkg-install@v2 + uses: neutrons/conda-actions/pkg-install@bba9ca89d48d9ae846db9650cc63fde736340b3d # v2 with: package-name: ${{ env.PKG_NAME }} local-channel: /tmp/local-channel - name: Verify conda package - uses: neutrons/conda-actions/pkg-verify@v2 + uses: neutrons/conda-actions/pkg-verify@bba9ca89d48d9ae846db9650cc63fde736340b3d # v2 with: package-name: ${{ env.PKG_NAME }} module-name: ${{ env.MODULE_NAME }} @@ -109,7 +109,7 @@ jobs: # Audit the dependencies of the conda package we just installed. SARIF # results are uploaded to GitHub code scanning by the grype action. - name: Scan installed environment with Grype - uses: neutrons/conda-actions/grype@v2 + uses: neutrons/conda-actions/grype@bba9ca89d48d9ae846db9650cc63fde736340b3d # v2 with: path: ${{ steps.install.outputs.conda_install_dir }} @@ -132,7 +132,7 @@ jobs: fetch-tags: true - name: Setup Pixi - uses: prefix-dev/setup-pixi@v0.9.6 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: manifest-path: pyproject.toml # Workaround: Dynamic versioning (versioningit) causes lock file version mismatch. @@ -149,7 +149,7 @@ jobs: name: artifact-conda-package - name: Upload package to anaconda - uses: neutrons/conda-actions/publish@v2 + uses: neutrons/conda-actions/publish@bba9ca89d48d9ae846db9650cc63fde736340b3d # v2 with: anaconda-token: ${{ secrets.ANACONDA_TOKEN }} organization: neutrons @@ -157,7 +157,7 @@ jobs: - name: Remove old packages if: github.ref == 'refs/heads/next' - uses: neutrons/conda-actions/pkg-remove@v2 + uses: neutrons/conda-actions/pkg-remove@bba9ca89d48d9ae846db9650cc63fde736340b3d # v2 with: anaconda_token: ${{ secrets.ANACONDA_TOKEN }} organization: neutrons @@ -180,7 +180,7 @@ jobs: fetch-tags: true - name: Setup pixi - uses: prefix-dev/setup-pixi@v0.9.6 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: manifest-path: pyproject.toml # Workaround: Dynamic versioning (versioningit) causes lock file version mismatch. @@ -202,4 +202,4 @@ jobs: # publish your distributions here (need to setup on PyPI first) - name: Publish package distributions to PyPI if: startsWith(github.ref, 'refs/tags/v') - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 diff --git a/.github/workflows/update-lockfiles.yml b/.github/workflows/update-lockfiles.yml index 46e6d0b..595aee9 100644 --- a/.github/workflows/update-lockfiles.yml +++ b/.github/workflows/update-lockfiles.yml @@ -18,7 +18,7 @@ jobs: # checks out refspec that triggered or the default branch - name: Setup pixi - uses: prefix-dev/setup-pixi@v0.9.6 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: run-install: false @@ -28,7 +28,7 @@ jobs: pixi update --json | pixi exec pixi-diff-to-markdown >> diff.md - name: Create pull request - uses: peter-evans/create-pull-request@v8 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8 # PR will target the branch checked out in the workflow with: token: ${{ secrets.GITHUB_TOKEN }} From e12ef6d8d76c08e7522b4096afa687d62d7554d5 Mon Sep 17 00:00:00 2001 From: Chen Zhang Date: Mon, 22 Jun 2026 13:13:40 -0400 Subject: [PATCH 2/2] security: bump msgpack-python to clear pip-audit Pin msgpack-python>=1.2.1 (GHSA-6v7p-g79w-8964) in the pip-audit security block and regenerate pixi.lock. pip-audit now reports no known vulnerabilities. Assisted-With: Claude Opus 4.8 --- pixi.lock | 30 ++++++++++++++++-------------- pyproject.toml | 1 + 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/pixi.lock b/pixi.lock index c71af30..58276d8 100644 --- a/pixi.lock +++ b/pixi.lock @@ -100,7 +100,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py314h9891dd4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.2.1-py314h9891dd4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nh3-0.3.5-py310hd8a072f_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda @@ -486,7 +486,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.6-hc7d1edf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.2.1-py314h6cfcd04_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nh3-0.3.5-py310h3b8a9b8_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nspr-4.38-heaf21c2_0.conda @@ -639,7 +639,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py314h9891dd4_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.2.1-py314h9891dd4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda @@ -1085,7 +1085,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.6-hc7d1edf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.9-py314hc042b31_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.2.1-py314h6cfcd04_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nspr-4.38-heaf21c2_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.118-h1c710a3_0.conda @@ -2351,9 +2351,9 @@ packages: license_family: LGPL size: 491140 timestamp: 1730581373280 -- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.1.2-py314h9891dd4_1.conda - sha256: d41c2734d314303e329680aeef282766fe399a0ce63297a68a2f8f9b43b1b68a - md5: c6752022dcdbf4b9ef94163de1ab7f03 +- conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.2.1-py314h9891dd4_0.conda + sha256: bbbb210e90dbd8c9ddba24730aca81aefe23f5ecaf79a81b6740e0dbd25f7b21 + md5: 9b67bf9c63607097b6e010a7b555a388 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 @@ -2362,8 +2362,9 @@ packages: - python_abi 3.14.* *_cp314 license: Apache-2.0 license_family: Apache - size: 103380 - timestamp: 1762504077009 + run_exports: {} + size: 103513 + timestamp: 1782070374726 - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 md5: fc21868a1a5aacc937e7a18747acb8a5 @@ -6431,9 +6432,9 @@ packages: license_family: PSF size: 8315491 timestamp: 1777001530326 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.1.2-py314h784bc60_1.conda - sha256: 9dc4ebe88064cf96bb97a4de83be10fbc52a24d2ff48a4561fb0fed337b526f0 - md5: 305227e4de261896033ad8081e8b52ae +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.2.1-py314h6cfcd04_0.conda + sha256: 09ea486f9248fdd987430a3519c31a0331e903edecc9740586a3e0abd590f840 + md5: 7f80c3267c4b89767d7bbdf36d69fe80 depends: - __osx >=11.0 - libcxx >=19 @@ -6442,8 +6443,9 @@ packages: - python_abi 3.14.* *_cp314 license: Apache-2.0 license_family: Apache - size: 92381 - timestamp: 1762504601981 + run_exports: {} + size: 92074 + timestamp: 1782070774684 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda sha256: 4ea6c620b87bd1d42bb2ccc2c87cd2483fa2d7f9e905b14c223f11ff3f4c455d md5: 343d10ed5b44030a2f67193905aea159 diff --git a/pyproject.toml b/pyproject.toml index fd539a0..7c2156e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,6 +116,7 @@ virtualenv = ">=20.36.1,<21" # Known vulnerability in <20.36.1; capped due to ht cryptography = ">=48.0.1" # CVE-2026-26007, CVE-2026-39892, GHSA-537c-gmf6-5ccf requests = ">=2.33.0" # CVE-2026-25645 pillow = ">=12.2.0" # CVE-2026-25990, CVE-2026-40192 +msgpack-python = ">=1.2.1" # GHSA-6v7p-g79w-8964 [tool.pixi.pypi-dependencies] # PyPI dependencies, including this package to allow local editable installs