From 1a5c33bfac5c555f86429b4a7cc4f630f72600f7 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 19 May 2026 19:46:32 -0500 Subject: [PATCH 1/3] Tighten GITHUB_TOKEN scope on bandit, codeql, publish, python workflows OSSF Scorecard's token-permissions check was scoring 0. Default GITHUB_TOKEN scope is write, so workflows that don't declare permissions inherit too much. scorecard.yml was already locked down; the other four weren't. Top-level read-all on each, with the write bits scoped to the jobs that actually need them: - bandit.yml: analyze keeps security-events: write - codeql.yml: analyze keeps security-events: write plus actions/contents: read - publish.yml: publish keeps id-token: write for PyPI OIDC - python.yml: build keeps pull-requests: write for the coverage comment --- .github/workflows/bandit.yml | 2 ++ .github/workflows/codeql.yml | 2 ++ .github/workflows/publish.yml | 2 ++ .github/workflows/python.yml | 2 ++ 4 files changed, 8 insertions(+) diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml index 58d698c..3129971 100644 --- a/.github/workflows/bandit.yml +++ b/.github/workflows/bandit.yml @@ -10,6 +10,8 @@ on: - cron: "0 0 * * 0" workflow_dispatch: +permissions: read-all + jobs: analyze: runs-on: ubuntu-latest diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0450a53..f94a5e4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -8,6 +8,8 @@ on: schedule: - cron: "0 0 * * 0" +permissions: read-all + jobs: analyze: name: Analyze Python diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e732a45..90b3c85 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,8 @@ on: release: types: [published] +permissions: read-all + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 1174e8e..1a26a9c 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -2,6 +2,8 @@ name: Python CI on: [push, pull_request] +permissions: read-all + jobs: build: permissions: From 8410499ee3adaf4c8b9aa8a304267e56c2b959c7 Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 19 May 2026 19:53:33 -0500 Subject: [PATCH 2/3] Enable Dependabot for github-actions and pip ecosystems OSSF Scorecard's dependency-update-tool check was scoring 0. The project has no runtime dependencies, but the action versions in .github/workflows and the test-only deps in requirements.txt are both worth keeping fresh so we don't ship CI on stale, vulnerable tooling. Weekly cadence on both ecosystems. Minor and patch bumps are grouped into a single PR per ecosystem to keep the noise bounded; major bumps still arrive as standalone PRs so the breaking-change review is honest. --- .github/dependabot.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..58600c6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + groups: + actions-minor-patch: + update-types: + - "minor" + - "patch" + + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + groups: + pip-minor-patch: + update-types: + - "minor" + - "patch" From 2a829f4eda435112259223844b79dc12ec29d5cd Mon Sep 17 00:00:00 2001 From: Tim Case Date: Tue, 19 May 2026 20:04:43 -0500 Subject: [PATCH 3/3] Pin GitHub Actions to commit SHAs, drop unmaintained coverage comment OSSF Scorecard's pinned-dependencies check was at 1/10. Out of 14 GitHub-owned action references only 3 were SHA-pinned (all in scorecard.yml from PR #138); the rest were on floating tags like @v4 or, in one third-party case, on a branch ref (@main). Floating refs are mutable; supply-chain attacks on actions become silent on push. Pinning every reference to a full-length commit SHA with the human- readable version as a trailing comment. Dependabot already runs on the github-actions ecosystem (added earlier in this PR) so the version comments stay fresh as bumps land. Workflow-by-workflow: - bandit.yml: pin actions/checkout v6.0.2, PyCQA/bandit-action v1.0.1 - codeql.yml: pin actions/checkout v6.0.2 and all three github/codeql-action sub-paths (init, autobuild, analyze) to v4.35.3 - publish.yml: pin actions/checkout v6.0.2, actions/setup-python v6.2.0, actions/upload-artifact v4.6.2, actions/download-artifact v4.3.0, and pypa/gh-action-pypi-publish v1.14.0 (was @release/v1 branch) - python.yml: pin actions/checkout v6.0.2, actions/setup-python v6.2.0; drop MishaKav/pytest-coverage-comment@main step entirely. It was the only third-party action on a moving branch ref and the only reason the build job needed pull-requests: write. Coverage still gets printed to the workflow log via pytest --cov-report term-missing. The pip-install commands in these workflows are still unpinned. That's a follow-up PR -- requires generating a hash-pinned requirements.txt with pip-tools and reworking the install steps. --- .github/workflows/bandit.yml | 4 ++-- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/publish.yml | 10 +++++----- .github/workflows/python.yml | 13 ++----------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml index 3129971..c28a2f8 100644 --- a/.github/workflows/bandit.yml +++ b/.github/workflows/bandit.yml @@ -21,9 +21,9 @@ jobs: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: - name: Checkout code - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Perform Bandit Analysis - uses: PyCQA/bandit-action@v1 + uses: PyCQA/bandit-action@ca64e96d362b1764a98d841aaf3a4b1e2d690c7b # v1.0.1 with: targets: "bitmath/ tests/" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f94a5e4..b0cc72b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,17 +23,17 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: languages: python - name: Autobuild - uses: github/codeql-action/autobuild@v4 + uses: github/codeql-action/autobuild@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: category: "/language:python" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 90b3c85..b90d2e7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,14 +12,14 @@ jobs: env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true steps: - - uses: actions/checkout@v6.0.2 - - uses: actions/setup-python@v6.2.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.12" - name: Build package run: pip install build && python -m build - name: Upload dist artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: dist path: dist/ @@ -32,9 +32,9 @@ jobs: id-token: write steps: - name: Download dist artifacts - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: dist path: dist/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 1a26a9c..25d96b9 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -6,8 +6,6 @@ permissions: read-all jobs: build: - permissions: - pull-requests: write env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true strategy: @@ -17,10 +15,10 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: "GitHub Checks it out :sunglasses-face:" - uses: actions/checkout@v6.0.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6.2.0 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python-version }} cache: 'pip' @@ -47,10 +45,3 @@ jobs: - name: Run Unit Tests run: | pytest -v --cov=bitmath --cov-report term-missing --cov-report term:skip-covered --cov-report xml:coverage.xml tests - - - name: Coverage report on PR - if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' - uses: MishaKav/pytest-coverage-comment@main - with: - pytest-xml-coverage-path: ./coverage.xml - title: "Test Coverage Report"