From d18c5eb3e193965995deeb4dc5d51a94c133d89d Mon Sep 17 00:00:00 2001 From: jmeridth Date: Wed, 3 Jun 2026 18:25:43 -0500 Subject: [PATCH] ci: pin actions to SHAs and harden workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Pin all GitHub Actions to full commit SHAs (with version comments) and apply baseline security hardening from the gha-standards skill across both workflows. ## Why Floating tag references (e.g. @v6) can be re-pointed if a maintainer account is compromised. SHA pinning prevents supply-chain swaps. The accompanying hardening (workflow-level permissions:{}, job-scoped permissions with justification, harden-runner egress monitoring, persist-credentials:false on checkout, PR-aware concurrency) applies least-privilege defaults. ## Notes - harden-runner is set to egress-policy: audit, not block. It will report unexpected network calls but not fail the build. Switch to block only after reviewing a few audit runs. - contributors.yml omits a concurrency block intentionally — it's schedule/workflow_dispatch only, where concurrent runs are not a concern. - ci.yml's concurrency uses github.head_ref || github.ref so PRs each get their own group, and cancel-in-progress only fires on pull_request events so post-submit push runs aren't interrupted. - permissions:{} at workflow level is deny-all. New jobs added later without their own permissions: block will have no token scopes — reviewers should watch for that. - contributors.yml's job has discussions:write but no contents:read. The create-discussion step reads ./contributors.md generated by the prior contributors step in the same workspace, so no checkout is needed — worth a watch on the next scheduled run. Signed-off-by: jmeridth --- .github/workflows/ci.yml | 18 ++++++++++++++---- .github/workflows/contributors.yml | 13 +++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8253d95..17baca2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,15 +6,25 @@ on: - "dependabot/**" pull_request: -permissions: - contents: read +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: lint: runs-on: ubuntu-latest + permissions: + contents: read # Clone the repository steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v6 + - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: cache: npm - name: Install dependencies diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml index 7d4db82..d50377c 100644 --- a/.github/workflows/contributors.yml +++ b/.github/workflows/contributors.yml @@ -4,15 +4,20 @@ on: schedule: - cron: "3 2 1 * *" -permissions: - discussions: write +permissions: {} jobs: contributor_report: name: contributor reports runs-on: ubuntu-latest + permissions: + discussions: write # Create the monthly thank-you discussion via abirismyname/create-discussion steps: + - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + - name: Get dates for last month shell: bash run: | @@ -27,7 +32,7 @@ jobs: echo "END_DATE=$end_date" >> "$GITHUB_ENV" - name: Run contributor action - uses: github-community-projects/contributors@v2 + uses: github-community-projects/contributors@4fda46a62ca1f1f1162c053c11d9576ae0cdda99 # v2.0.15 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} START_DATE: ${{ env.START_DATE }} @@ -37,7 +42,7 @@ jobs: LINK_TO_PROFILE: "true" - name: Create GitHub Discussion - uses: abirismyname/create-discussion@v2.1.0 + uses: abirismyname/create-discussion@c2b7c825241769dda523865ae444a879f6bbd0e0 # v2.1.0 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: