From e187c15d1baf0a68ba8297407c9cf72f7ba28563 Mon Sep 17 00:00:00 2001 From: michalharakal Date: Sun, 9 Aug 2026 20:57:11 +0200 Subject: [PATCH] ci: give every workflow a least-privilege GITHUB_TOKEN Fixes the Scorecard Token-Permissions check, which scored 0 because six workflows declared no top-level permissions and so inherited whatever the repository default grants: engine-benchmarks.yml, java-tests.yml, native-cpu-multiarch.yml, publish.yml, schema-validation.yml, verify-poms.yml All six now follow the pattern build.yml and reuse-compliance.yml already used: top-level `permissions: {}`, with each job granted only what it needs. Every one of them is read-only CI -- checkout, setup-java, cache and upload-artifact -- so `contents: read` is the whole requirement. upload-artifact authenticates with the Actions runtime token rather than GITHUB_TOKEN, and publish.yml reaches Maven Central and GPG through repository secrets, which are independent of GITHUB_TOKEN, so nothing here loses access it was using. Also moved two top-level write grants down to the single job that needs them, which is the other half of what this check penalises: docs.yml pages/id-token write reached build-docs as well as deploy-docs; only deploy-pages needs them documentation.yml pull-requests write reached build-documentation as well as preview-documentation; only the github-script comment step needs it No workflow now holds a write permission at top level, and no job holds a permission it does not exercise. --- .github/workflows/docs.yml | 16 ++++++++++++---- .github/workflows/documentation.yml | 19 ++++++++++++++----- .github/workflows/engine-benchmarks.yml | 11 +++++++++++ .github/workflows/java-tests.yml | 6 ++++++ .github/workflows/native-cpu-multiarch.yml | 6 ++++++ .github/workflows/publish.yml | 13 +++++++++++++ .github/workflows/schema-validation.yml | 6 ++++++ .github/workflows/verify-poms.yml | 6 ++++++ 8 files changed, 74 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 26b764204..f6c402530 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -36,16 +36,18 @@ concurrency: group: docs-${{ github.ref }} cancel-in-progress: true -permissions: - contents: read - pages: write - id-token: write +# Set default permission for all jobs to none. The Pages write grants live on +# deploy-docs alone — build-docs only reads the repo and uploads an artifact. +permissions: {} jobs: build-docs: runs-on: ubuntu-latest timeout-minutes: 30 + permissions: + contents: read + steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -136,6 +138,12 @@ jobs: name: github-pages url: ${{ steps.deployment.outputs.page_url }} + # actions/deploy-pages needs pages:write to publish and id-token:write for + # the OIDC token it exchanges. It does not check the repository out. + permissions: + pages: write + id-token: write + steps: - name: Deploy to GitHub Pages id: deployment diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 9292d9994..640554b71 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -16,15 +16,18 @@ on: - 'docs/**' - '.github/workflows/documentation.yml' -permissions: - contents: read - pull-requests: write +# Set default permission for all jobs to none. Only preview-documentation posts +# the PR comment, so pull-requests:write lives there rather than build-wide. +permissions: {} jobs: build-documentation: runs-on: ubuntu-latest timeout-minutes: 40 - + + permissions: + contents: read + steps: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -78,7 +81,13 @@ jobs: if: github.event_name == 'pull_request' needs: build-documentation runs-on: ubuntu-latest - + + # Posts the preview comment via actions/github-script. PR comments are issue + # comments, so pull-requests:write is what listComments/createComment need. + permissions: + contents: read + pull-requests: write + steps: - name: Download documentation artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 diff --git a/.github/workflows/engine-benchmarks.yml b/.github/workflows/engine-benchmarks.yml index 7526b1781..f36230953 100644 --- a/.github/workflows/engine-benchmarks.yml +++ b/.github/workflows/engine-benchmarks.yml @@ -34,6 +34,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Set default permission for all jobs to none +permissions: {} + jobs: smoke-ubuntu-latest: # Smoke pack on the default GitHub runner. Goal: prove the harness + @@ -42,6 +45,10 @@ jobs: # runner, shared tenancy, no warmup steady-state. runs-on: ubuntu-latest timeout-minutes: 20 + + permissions: + contents: read + steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -92,6 +99,10 @@ jobs: if: github.event_name == 'workflow_dispatch' || github.event_name == 'release' runs-on: [self-hosted, linux, x86_64, skainet-bench-linux-x86] timeout-minutes: 120 + + permissions: + contents: read + steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/java-tests.yml b/.github/workflows/java-tests.yml index e7dcab2ca..1dd962ee8 100644 --- a/.github/workflows/java-tests.yml +++ b/.github/workflows/java-tests.yml @@ -10,11 +10,17 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Set default permission for all jobs to none +permissions: {} + jobs: java-tests: runs-on: ubuntu-latest timeout-minutes: 30 + permissions: + contents: read + steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/native-cpu-multiarch.yml b/.github/workflows/native-cpu-multiarch.yml index 154744655..d4c2a73fc 100644 --- a/.github/workflows/native-cpu-multiarch.yml +++ b/.github/workflows/native-cpu-multiarch.yml @@ -30,6 +30,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Set default permission for all jobs to none +permissions: {} + jobs: native-build-test: name: ${{ matrix.arch_label }} @@ -53,6 +56,9 @@ jobs: runs-on: ${{ matrix.os }} timeout-minutes: 30 + permissions: + contents: read + steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bfbd220c4..338a9156f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,6 +31,11 @@ on: tags: - '**' +# Set default permission for all jobs to none. Publishing authenticates to Maven +# Central and signs with GPG through repository secrets, which are independent of +# GITHUB_TOKEN — nothing here needs write access to the repository itself. +permissions: {} + jobs: build-native: name: native ${{ matrix.arch_label }} @@ -49,6 +54,10 @@ jobs: lib_name: skainet_kernels.dll runs-on: ${{ matrix.os }} timeout-minutes: 30 + + permissions: + contents: read + steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -91,6 +100,10 @@ jobs: name: Release build and publish needs: build-native runs-on: macOS-latest + + permissions: + contents: read + steps: - name: Check out code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/schema-validation.yml b/.github/workflows/schema-validation.yml index 929f0321e..b270bfcc4 100644 --- a/.github/workflows/schema-validation.yml +++ b/.github/workflows/schema-validation.yml @@ -9,9 +9,15 @@ on: - 'skainet-lang/**' - '.github/workflows/schema-validation.yml' +# Set default permission for all jobs to none +permissions: {} + jobs: validate-schema: runs-on: ubuntu-latest + + permissions: + contents: read steps: - name: Checkout code diff --git a/.github/workflows/verify-poms.yml b/.github/workflows/verify-poms.yml index 103dd2365..0a7e62f73 100644 --- a/.github/workflows/verify-poms.yml +++ b/.github/workflows/verify-poms.yml @@ -10,12 +10,18 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Set default permission for all jobs to none +permissions: {} + jobs: verify-poms: name: Publish to Maven local and validate POM coordinates runs-on: ubuntu-latest timeout-minutes: 45 + permissions: + contents: read + steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1