diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index ac43043c..5f179499 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -22,6 +22,13 @@ on: required: false default: "10" +# Least-privilege default for the auto-injected GITHUB_TOKEN. The single job +# only builds and uploads an artifact (upload-artifact uses the artifact +# storage API, not the contents scope), so it never needs repo write (OpenSSF +# Scorecard: Token-Permissions). +permissions: + contents: read + env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91ce89dd..7ef29e5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,13 @@ on: pull_request: branches: [main] +# Least-privilege default for the auto-injected GITHUB_TOKEN. None of the CI +# jobs write back to the repo — coverage uploads via CODECOV_TOKEN, everything +# else is build/test/lint — so a read-only token is sufficient (OpenSSF +# Scorecard: Token-Permissions). +permissions: + contents: read + env: CARGO_TERM_COLOR: always RUSTFLAGS: "-D warnings" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 215d58e6..4bb6a168 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,6 +12,13 @@ on: schedule: - cron: '31 3 * * 0' # Sundays 03:31 UTC +# Least-privilege default for the auto-injected GITHUB_TOKEN. The analyze job +# raises exactly the scopes CodeQL needs (security-events: write to upload +# results) in its own job-level block below; this top-level read-only default +# covers any future job (OpenSSF Scorecard: Token-Permissions). +permissions: + contents: read + jobs: analyze: name: Analyze (${{ matrix.language }}) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fcd1460..35b63490 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,17 @@ on: tags: ["v*"] workflow_dispatch: +# Least-privilege default for the auto-injected GITHUB_TOKEN. The publish jobs +# (cargo/python/node) push to external registries via their own secrets +# (CARGO_REGISTRY_TOKEN / PYPI_API_TOKEN / NPM_TOKEN), not the GITHUB_TOKEN, so +# they need no repo write. The jobs that genuinely write through the +# GITHUB_TOKEN — github-release (contents: write), node-/wasm-publish and +# attestations (id-token / attestations: write) — declare those rights in their +# own job-level permissions blocks, which override this default (OpenSSF +# Scorecard: Token-Permissions). +permissions: + contents: read + env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/sync-about.yml b/.github/workflows/sync-about.yml index cf1a0c61..f9c65de7 100644 --- a/.github/workflows/sync-about.yml +++ b/.github/workflows/sync-about.yml @@ -55,18 +55,24 @@ on: types: [opened, synchronize, reopened] workflow_dispatch: -# `contents: write` is needed so the workflow can push the counter -# fix-up commit to the PR head branch via the auto-provided -# GITHUB_TOKEN. The wider About / Wiki writes still go through the -# fine-grained PAT (ABOUT_SYNC_TOKEN) because they need -# `Administration: write` (gh repo edit) which GITHUB_TOKEN lacks. +# Least-privilege default for the auto-injected GITHUB_TOKEN. The `contents: +# write` the workflow needs — to push the counter fix-up commit to the PR head +# branch — is raised at the job level below, not here, so the top-level default +# stays read-only (OpenSSF Scorecard: Token-Permissions). The wider About / +# docs / webpage / org writes still go through the fine-grained PAT +# (ABOUT_SYNC_TOKEN), which the `permissions:` key does not govern at all. permissions: - contents: write + contents: read pull-requests: read jobs: sync: runs-on: ubuntu-latest + # The only GITHUB_TOKEN write in this workflow: pushing the counter fix-up + # commit onto a same-repo PR head branch (git push origin HEAD:). + permissions: + contents: write + pull-requests: read steps: # On PRs from forks the head ref lives in another repo; pushing # back to it from this workflow is blocked by GitHub. We still