From e347d692e6441c9aec1895ee840fdc87e66fcd26 Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Thu, 29 Oct 2026 14:40:50 +0100 Subject: [PATCH 1/5] ci: declare what each workflow may do with the job token Seven workflows had no permissions block, so their jobs ran with the repository's default token scopes. They read the tree, build and test, or post to Slack with the bot token, so the workflow level says contents: read. Two jobs write with the job token and say so: the integration run on a fork updates its own check run, the labeler creates and updates the repository labels. CodeQL, the release notes cleanup and dependency review keep the blocks they already declare. --- .github/workflows/ci.yml | 3 +++ .github/workflows/integration_tests_pr.yml | 8 ++++++++ .github/workflows/labeler.yml | 7 +++++++ .github/workflows/nightly_smoke_tests.yml | 3 +++ .github/workflows/release-cross-repo-test.yml | 3 +++ .github/workflows/release-notify-slack.yml | 3 +++ .github/workflows/security_pr.yml | 3 +++ 7 files changed, 30 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9917bafeb..27a3ab819 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,9 @@ on: - main pull_request: null +permissions: + contents: read + jobs: lint-tidy: runs-on: ubuntu-latest diff --git a/.github/workflows/integration_tests_pr.yml b/.github/workflows/integration_tests_pr.yml index 4d2e07e5b..b8caee214 100644 --- a/.github/workflows/integration_tests_pr.yml +++ b/.github/workflows/integration_tests_pr.yml @@ -22,8 +22,16 @@ on: name: Integration tests on PR +permissions: + contents: read + jobs: integration-fork: + permissions: + contents: read + # Reads the pull request head and updates this job's check run. + pull-requests: read + checks: write runs-on: ubuntu-latest if: github.event_name == 'workflow_dispatch' && inputs.sha != '' steps: diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 394ec5de9..a5bcdac60 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -12,8 +12,15 @@ on: - '.github/labels.yml' - '.github/workflows/labeler.yml' +permissions: + contents: read + jobs: labeler: + permissions: + contents: read + # Label sync creates and updates the repository labels. + issues: write runs-on: ubuntu-latest steps: - diff --git a/.github/workflows/nightly_smoke_tests.yml b/.github/workflows/nightly_smoke_tests.yml index f0de06b5b..0f5dd77f3 100644 --- a/.github/workflows/nightly_smoke_tests.yml +++ b/.github/workflows/nightly_smoke_tests.yml @@ -11,6 +11,9 @@ on: default: '' type: string +permissions: + contents: read + jobs: smoke_tests: if: github.repository == 'linode/linodego' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/release-cross-repo-test.yml b/.github/workflows/release-cross-repo-test.yml index 160f7c435..35e3c1da0 100644 --- a/.github/workflows/release-cross-repo-test.yml +++ b/.github/workflows/release-cross-repo-test.yml @@ -3,6 +3,9 @@ name: Release Terraform cross repository test on: workflow_dispatch: # Manual trigger +permissions: + contents: read + jobs: terraform_integration_test: runs-on: ubuntu-latest diff --git a/.github/workflows/release-notify-slack.yml b/.github/workflows/release-notify-slack.yml index 534ea9d63..7c6be4d21 100644 --- a/.github/workflows/release-notify-slack.yml +++ b/.github/workflows/release-notify-slack.yml @@ -4,6 +4,9 @@ on: types: [published] workflow_dispatch: null +permissions: + contents: read + jobs: notify: if: github.repository == 'linode/linodego' diff --git a/.github/workflows/security_pr.yml b/.github/workflows/security_pr.yml index 759efaded..d68756b2d 100644 --- a/.github/workflows/security_pr.yml +++ b/.github/workflows/security_pr.yml @@ -2,6 +2,9 @@ name: Security Checks for Pull Requests on: pull_request: null +permissions: + contents: read + jobs: dependency-review: permissions: From b211f9d21e81b305de8e6293c172cb20f9602aa4 Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Thu, 29 Oct 2026 14:40:50 +0100 Subject: [PATCH 2/5] ci: stop persisting the checkout token, no job pushes with git actions/checkout leaves the job token in .git/config by default, where every later step and tool in the job can read it. The eleven checkouts opt out: the test report goes to object storage with its own keys and nothing pushes with git. --- .github/workflows/ci.yml | 3 +++ .github/workflows/codeql.yml | 2 ++ .github/workflows/integration_tests_pr.yml | 2 ++ .github/workflows/labeler.yml | 2 ++ .github/workflows/nightly_smoke_tests.yml | 1 + .github/workflows/release-cross-repo-test.yml | 2 ++ .github/workflows/security_pr.yml | 4 ++++ 7 files changed, 16 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27a3ab819..b7db9065c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,6 +60,8 @@ jobs: GITHUB_TOKEN: ${{ github.token }} - uses: actions/checkout@v7 + with: + persist-credentials: false - uses: actions/setup-go@v7 with: go-version: stable @@ -88,6 +90,7 @@ jobs: - name: Clone Repository uses: actions/checkout@v7 with: + persist-credentials: false fetch-depth: 0 submodules: 'recursive' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c773e45c0..60c846614 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,6 +24,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@v4 diff --git a/.github/workflows/integration_tests_pr.yml b/.github/workflows/integration_tests_pr.yml index b8caee214..9276fc607 100644 --- a/.github/workflows/integration_tests_pr.yml +++ b/.github/workflows/integration_tests_pr.yml @@ -50,6 +50,7 @@ jobs: - name: Checkout PR uses: actions/checkout@v7 with: + persist-credentials: false ref: ${{ inputs.sha }} - run: make ARGS="-run $MODULE" fixtures @@ -127,6 +128,7 @@ jobs: - name: Checkout code uses: actions/checkout@v7 with: + persist-credentials: false fetch-depth: 0 submodules: 'recursive' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index a5bcdac60..39fb7cf5f 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -26,6 +26,8 @@ jobs: - name: Checkout uses: actions/checkout@v7 + with: + persist-credentials: false - name: Run Labeler uses: crazy-max/ghaction-github-labeler@548a7c3603594ec17c819e1239f281a3b801ab4d diff --git a/.github/workflows/nightly_smoke_tests.yml b/.github/workflows/nightly_smoke_tests.yml index 0f5dd77f3..6c3fa2d12 100644 --- a/.github/workflows/nightly_smoke_tests.yml +++ b/.github/workflows/nightly_smoke_tests.yml @@ -23,6 +23,7 @@ jobs: - name: Checkout code uses: actions/checkout@v7 with: + persist-credentials: false fetch-depth: 0 submodules: 'recursive' ref: ${{ github.event.inputs.sha || github.ref }} diff --git a/.github/workflows/release-cross-repo-test.yml b/.github/workflows/release-cross-repo-test.yml index 35e3c1da0..57777a285 100644 --- a/.github/workflows/release-cross-repo-test.yml +++ b/.github/workflows/release-cross-repo-test.yml @@ -13,6 +13,7 @@ jobs: - name: checkout terraform repo uses: actions/checkout@v7 with: + persist-credentials: false repository: linode/terraform-provider-linode fetch-depth: 0 submodules: 'recursive' @@ -27,6 +28,7 @@ jobs: - name: Clone Repository uses: actions/checkout@v7 with: + persist-credentials: false path: linodego - name: Set up linodego diff --git a/.github/workflows/security_pr.yml b/.github/workflows/security_pr.yml index d68756b2d..325f68987 100644 --- a/.github/workflows/security_pr.yml +++ b/.github/workflows/security_pr.yml @@ -14,6 +14,8 @@ jobs: steps: - name: 'Checkout repository' uses: actions/checkout@v7 + with: + persist-credentials: false - name: 'Dependency Review' uses: actions/dependency-review-action@v5 with: @@ -26,6 +28,8 @@ jobs: steps: - name: Checkout Source uses: actions/checkout@v7 + with: + persist-credentials: false - name: Run Gosec Security Scanner on root directory uses: securego/gosec@master From c3465965893acc1c50f3fa3a1f7f2092a4e200cc Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Thu, 29 Oct 2026 14:40:50 +0100 Subject: [PATCH 3/5] ci: run the gosec release instead of its master branch The security scan tracked the master branch of its action, which changes with every push there. It now references the v2.30.0 release, so the lockfile below holds one commit for it. --- .github/workflows/security_pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/security_pr.yml b/.github/workflows/security_pr.yml index 325f68987..b758dbdd7 100644 --- a/.github/workflows/security_pr.yml +++ b/.github/workflows/security_pr.yml @@ -32,7 +32,7 @@ jobs: persist-credentials: false - name: Run Gosec Security Scanner on root directory - uses: securego/gosec@master + uses: securego/gosec@v2.30.0 with: # We need to temporarily exclude this as gosec doesn't # support using module files from subdirectories. From 5e5df3e20e43e919b0a789a29d1d849596442652 Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Thu, 29 Oct 2026 14:40:50 +0100 Subject: [PATCH 4/5] ci: record every action's commit in a workflow lockfile GitHub's workflow dependency lockfile holds the commit each action reference resolves to, transitive actions included, and the runner uses those commits even if a tag moves later. .github/workflows/actions.lock comes from gh actions-lock (v0.4.0), which also narrowed every reference to the exact release it locked, so Dependabot keeps bumping versions and its security alerts keep matching. Re-run the same command after adding or bumping an action. --- .github/workflows/actions.lock | 106 ++++++++++++++++++ .github/workflows/ci.yml | 16 +-- .github/workflows/clean-release-notes.yml | 2 +- .github/workflows/codeql.yml | 6 +- .github/workflows/integration_tests_pr.yml | 12 +- .github/workflows/labeler.yml | 4 +- .github/workflows/nightly_smoke_tests.yml | 6 +- .github/workflows/release-cross-repo-test.yml | 6 +- .github/workflows/release-notify-slack.yml | 2 +- .github/workflows/security_pr.yml | 6 +- 10 files changed, 136 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/actions.lock diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock new file mode 100644 index 000000000..001bed90f --- /dev/null +++ b/.github/workflows/actions.lock @@ -0,0 +1,106 @@ +# This file is machine-generated by `gh actions-lock`. +# Do not edit by hand; run `gh actions-lock` to update. +# Docs: https://gh.io/actions-lockfile +version: 'v0.0.3' +workflows: + '.github/workflows/ci.yml': + - 'actions/checkout@v7.0.1' + - 'actions/setup-go@v7.0.0' + - 'actions/setup-python@v7.1.0' + - 'amannn/action-semantic-pull-request@v6.1.1' + - 'golangci/golangci-lint-action@v9.3.0' + - 'slackapi/slack-github-action@v4.0.0' + '.github/workflows/clean-release-notes.yml': + - 'actions/github-script@v9.0.0' + '.github/workflows/codeql.yml': + - 'actions/checkout@v7.0.1' + - 'github/codeql-action@v4.39.1' + '.github/workflows/integration_tests_pr.yml': + - 'actions-ecosystem/action-regex-match@v2.0.2' + - 'actions/checkout@v7.0.1' + - 'actions/github-script@v9.0.0' + - 'actions/setup-go@v7.0.0' + - 'actions/setup-python@v7.1.0' + - 'octokit/graphql-action@v2.x' + '.github/workflows/labeler.yml': + - 'actions/checkout@v7.0.1' + - 'crazy-max/ghaction-github-labeler@v6.0.0' + '.github/workflows/nightly_smoke_tests.yml': + - 'actions/checkout@v7.0.1' + - 'actions/setup-go@v7.0.0' + - 'slackapi/slack-github-action@v4.0.0' + '.github/workflows/release-cross-repo-test.yml': + - 'actions/checkout@v7.0.1' + - 'actions/setup-go@v7.0.0' + '.github/workflows/release-notify-slack.yml': + - 'slackapi/slack-github-action@v4.0.0' + '.github/workflows/security_pr.yml': + - 'actions/checkout@v7.0.1' + - 'actions/dependency-review-action@v5.0.0' + - 'securego/gosec@v2.30.0' +dependencies: + 'actions-ecosystem/action-regex-match@v2.0.2': + ref: 'v2.0.2' + commit: 'sha1-9e6c4fb3d5e898f505be7a1fb6e7b0a278f6665b' + owner_id: 56633079 + repo_id: 261130368 + 'actions/checkout@v7.0.1': + ref: 'v7.0.1' + commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1' + owner_id: 44036562 + repo_id: 197814629 + 'actions/dependency-review-action@v5.0.0': + ref: 'v5.0.0' + commit: 'sha1-a1d282b36b6f3519aa1f3fc636f609c47dddb294' + owner_id: 44036562 + repo_id: 476372928 + 'actions/github-script@v9.0.0': + ref: 'v9.0.0' + commit: 'sha1-3a2844b7e9c422d3c10d287c895573f7108da1b3' + owner_id: 44036562 + repo_id: 205262760 + 'actions/setup-go@v7.0.0': + ref: 'v7.0.0' + commit: 'sha1-b7ad1dad31e06c5925ef5d2fc7ad053ef454303e' + owner_id: 44036562 + repo_id: 192624594 + 'actions/setup-python@v7.1.0': + ref: 'v7.1.0' + commit: 'sha1-6d4fd22b20465ccc0f7354476588e8df7c9ca0e0' + owner_id: 44036562 + repo_id: 192625525 + 'amannn/action-semantic-pull-request@v6.1.1': + ref: 'v6.1.1' + commit: 'sha1-48f256284bd46cdaab1048c3721360e808335d50' + owner_id: 4038316 + repo_id: 220418983 + 'crazy-max/ghaction-github-labeler@v6.0.0': + ref: 'v6.0.0' + commit: 'sha1-548a7c3603594ec17c819e1239f281a3b801ab4d' + owner_id: 1951866 + repo_id: 216050313 + 'github/codeql-action@v4.39.1': + ref: 'v4.39.1' + commit: 'sha1-9b3254085494b55a0f7c4c2b3d2d52cc712ce370' + owner_id: 9919 + repo_id: 259445878 + 'golangci/golangci-lint-action@v9.3.0': + ref: 'v9.3.0' + commit: 'sha1-ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a' + owner_id: 35628013 + repo_id: 232539879 + 'octokit/graphql-action@v2.x': + ref: 'v2.x' + commit: 'sha1-f7836e89a7e5bac63911bbe9653c21147b3d9bc3' + owner_id: 3430433 + repo_id: 213717672 + 'securego/gosec@v2.30.0': + ref: 'v2.30.0' + commit: 'sha1-5eb1d104ef85ff2c905c877eb600e8c1dee33a22' + owner_id: 23195997 + repo_id: 63625434 + 'slackapi/slack-github-action@v4.0.0': + ref: 'v4.0.0' + commit: 'sha1-dcb1066f776dd043e64d0e8ba94ca15cc7e1875d' + owner_id: 6962987 + repo_id: 306439799 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7db9065c..36b480779 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: # - PRs labeled 'ignore-for-release' (release PRs that don't need a ticket prefix) - name: Validate PR Title if: github.event_name == 'pull_request' - uses: amannn/action-semantic-pull-request@v6 + uses: amannn/action-semantic-pull-request@v6.1.1 with: types: | TPT-\d+ @@ -59,15 +59,15 @@ jobs: env: GITHUB_TOKEN: ${{ github.token }} - - uses: actions/checkout@v7 + - uses: actions/checkout@v7.0.1 with: persist-credentials: false - - uses: actions/setup-go@v7 + - uses: actions/setup-go@v7.0.0 with: go-version: stable - name: golangci-lint - uses: golangci/golangci-lint-action@v9 + uses: golangci/golangci-lint-action@v9.3.0 with: version: latest @@ -88,20 +88,20 @@ jobs: EXIT_STATUS: 0 steps: - name: Clone Repository - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false fetch-depth: 0 submodules: 'recursive' - name: Set up Go - uses: actions/setup-go@v7 + uses: actions/setup-go@v7.0.0 with: go-version: 'stable' - run: go version - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@v7.1.0 with: python-version: '3.x' @@ -142,7 +142,7 @@ jobs: steps: - name: Notify Slack - uses: slackapi/slack-github-action@v4 + uses: slackapi/slack-github-action@v4.0.0 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/clean-release-notes.yml b/.github/workflows/clean-release-notes.yml index b2513a60b..c92f8a4f5 100644 --- a/.github/workflows/clean-release-notes.yml +++ b/.github/workflows/clean-release-notes.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Remove ticket prefixes from release notes - uses: actions/github-script@v9 + uses: actions/github-script@v9.0.0 with: script: | const release = context.payload.release; diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 60c846614..171397cf9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,18 +23,18 @@ jobs: build-mode: autobuild steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@v4.39.1 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} queries: security-and-quality - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@v4.39.1 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/integration_tests_pr.yml b/.github/workflows/integration_tests_pr.yml index 9276fc607..9e17aacce 100644 --- a/.github/workflows/integration_tests_pr.yml +++ b/.github/workflows/integration_tests_pr.yml @@ -35,11 +35,11 @@ jobs: runs-on: ubuntu-latest if: github.event_name == 'workflow_dispatch' && inputs.sha != '' steps: - - uses: actions/setup-go@v7 + - uses: actions/setup-go@v7.0.0 with: go-version: 'stable' - run: go version - - uses: actions-ecosystem/action-regex-match@v2 + - uses: actions-ecosystem/action-regex-match@v2.0.2 id: disallowed-char-check with: text: ${{ inputs.module }} @@ -48,7 +48,7 @@ jobs: # Check out merge commit - name: Checkout PR - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false ref: ${{ inputs.sha }} @@ -91,7 +91,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/github-script@v9 + - uses: actions/github-script@v9.0.0 id: update-check-run if: ${{ inputs.pull_request_number != '' && fromJson(steps.commit-hash.outputs.data).repository.pullRequest.headRef.target.oid == inputs.sha }} env: @@ -126,7 +126,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false fetch-depth: 0 @@ -153,7 +153,7 @@ jobs: steps: - name: Set up Python - uses: actions/setup-python@v7 + uses: actions/setup-python@v7.1.0 with: python-version: '3.x' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 39fb7cf5f..6b0ca5849 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -25,12 +25,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false - name: Run Labeler - uses: crazy-max/ghaction-github-labeler@548a7c3603594ec17c819e1239f281a3b801ab4d + uses: crazy-max/ghaction-github-labeler@v6.0.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} yaml-file: .github/labels.yml diff --git a/.github/workflows/nightly_smoke_tests.yml b/.github/workflows/nightly_smoke_tests.yml index 6c3fa2d12..ea7c9fec7 100644 --- a/.github/workflows/nightly_smoke_tests.yml +++ b/.github/workflows/nightly_smoke_tests.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false fetch-depth: 0 @@ -29,7 +29,7 @@ jobs: ref: ${{ github.event.inputs.sha || github.ref }} - name: Set up Go - uses: actions/setup-go@v7 + uses: actions/setup-go@v7.0.0 with: go-version: '1.x' @@ -42,7 +42,7 @@ jobs: - name: Notify Slack if: (success() || failure()) && github.repository == 'linode/linodego' - uses: slackapi/slack-github-action@v4 + uses: slackapi/slack-github-action@v4.0.0 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/release-cross-repo-test.yml b/.github/workflows/release-cross-repo-test.yml index 57777a285..2eff60b37 100644 --- a/.github/workflows/release-cross-repo-test.yml +++ b/.github/workflows/release-cross-repo-test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout terraform repo - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false repository: linode/terraform-provider-linode @@ -19,14 +19,14 @@ jobs: submodules: 'recursive' - name: Set up Go - uses: actions/setup-go@v7 + uses: actions/setup-go@v7.0.0 with: go-version: 'stable' - run: go version - run: make deps - name: Clone Repository - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false path: linodego diff --git a/.github/workflows/release-notify-slack.yml b/.github/workflows/release-notify-slack.yml index 7c6be4d21..d99c1488c 100644 --- a/.github/workflows/release-notify-slack.yml +++ b/.github/workflows/release-notify-slack.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify Slack - Main Message - uses: slackapi/slack-github-action@v4 + uses: slackapi/slack-github-action@v4.0.0 with: method: chat.postMessage token: ${{ secrets.SLACK_BOT_TOKEN }} diff --git a/.github/workflows/security_pr.yml b/.github/workflows/security_pr.yml index b758dbdd7..3d3ad8af3 100644 --- a/.github/workflows/security_pr.yml +++ b/.github/workflows/security_pr.yml @@ -13,11 +13,11 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout repository' - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false - name: 'Dependency Review' - uses: actions/dependency-review-action@v5 + uses: actions/dependency-review-action@v5.0.0 with: comment-summary-in-pr: on-failure @@ -27,7 +27,7 @@ jobs: GO111MODULE: on steps: - name: Checkout Source - uses: actions/checkout@v7 + uses: actions/checkout@v7.0.1 with: persist-credentials: false From 61022c9c27277eba64e85aafaeb3fc1bd40ee467 Mon Sep 17 00:00:00 2001 From: Thibaud-Vdb Date: Thu, 29 Oct 2026 14:40:50 +0100 Subject: [PATCH 5/5] ci: check the workflows with Plumber on every change and show the score A small workflow runs the Plumber CLI on pushes to main and on pull requests. It checks the GitHub workflows for the classes of findings the previous commits fixed (missing permissions, tokens left in checkouts, floating action refs) and fails under 85 points, so one small finding never blocks a pull request. Its two actions are recorded in actions.lock like the others. The overlay keeps the built-in defaults and trusts the four actions this repository uses on top of them. The README gets the score badge in the badge row. --- .github/workflows/actions.lock | 21 ++++++++++++++++++ .github/workflows/plumber.yml | 40 ++++++++++++++++++++++++++++++++++ .plumber.yaml | 17 +++++++++++++++ README.md | 1 + 4 files changed, 79 insertions(+) create mode 100644 .github/workflows/plumber.yml create mode 100644 .plumber.yaml diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index 001bed90f..c431e0415 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -29,6 +29,9 @@ workflows: - 'actions/checkout@v7.0.1' - 'actions/setup-go@v7.0.0' - 'slackapi/slack-github-action@v4.0.0' + '.github/workflows/plumber.yml': + - 'actions/checkout@v7.0.1' + - 'getplumber/plumber@v0.7.16' '.github/workflows/release-cross-repo-test.yml': - 'actions/checkout@v7.0.1' - 'actions/setup-go@v7.0.0' @@ -69,6 +72,11 @@ dependencies: commit: 'sha1-6d4fd22b20465ccc0f7354476588e8df7c9ca0e0' owner_id: 44036562 repo_id: 192625525 + 'actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9': + ref: 'v7.0.2' + commit: 'sha1-cf430e030ddbb5b0abf93d22962f4752f3646cd9' + owner_id: 44036562 + repo_id: 192625955 'amannn/action-semantic-pull-request@v6.1.1': ref: 'v6.1.1' commit: 'sha1-48f256284bd46cdaab1048c3721360e808335d50' @@ -79,6 +87,19 @@ dependencies: commit: 'sha1-548a7c3603594ec17c819e1239f281a3b801ab4d' owner_id: 1951866 repo_id: 216050313 + 'getplumber/plumber@v0.7.16': + ref: 'v0.7.16' + commit: 'sha1-e9ad2dc6d6faa2dfd84395aac18e461284062640' + owner_id: 255179076 + repo_id: 1137327132 + uses: + - 'actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9' + - 'github/codeql-action@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee' + 'github/codeql-action@6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee': + ref: 'v4.39.0' + commit: 'sha1-6f2ac81f5cd81fe351a197ba0b00d91d03cd2aee' + owner_id: 9919 + repo_id: 259445878 'github/codeql-action@v4.39.1': ref: 'v4.39.1' commit: 'sha1-9b3254085494b55a0f7c4c2b3d2d52cc712ce370' diff --git a/.github/workflows/plumber.yml b/.github/workflows/plumber.yml new file mode 100644 index 000000000..410d45eb9 --- /dev/null +++ b/.github/workflows/plumber.yml @@ -0,0 +1,40 @@ +name: Plumber + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + plumber: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + # Lets Plumber read the workflow states and one run log to prove + # the token scope. + actions: read + security-events: write + # Needed by score-push to publish the score for the README badge. + id-token: write + steps: + - uses: actions/checkout@v7.0.1 + with: + persist-credentials: false + + - uses: getplumber/plumber@v0.7.16 + with: + # Code scanning upload needs security-events write, which PRs + # from forks do not get. The report stays available as a + # workflow artifact there. + upload-sarif: ${{ github.event.pull_request.head.repo.fork != true }} + # Publishes the score to score.getplumber.io, which feeds the + # badge in the README. A failed push never fails the run. + score-push: true + # Gate at 85 points instead of the all-or-nothing default, + # leaves room for a small finding without blocking PRs. + min-points: 85 diff --git a/.plumber.yaml b/.plumber.yaml new file mode 100644 index 000000000..9212fe383 --- /dev/null +++ b/.plumber.yaml @@ -0,0 +1,17 @@ +# Plumber overlay: inherits every control from the CLI's built-in +# baseline, only the differences for this repository are written here. +# Run 'plumber config resolve' to see the full effective config. +extends: plumber:default +version: '2.0' + +github: + controls: + githubActionMustComeFromAuthorizedSources: + # Keep the curated default list and trust the actions this + # repository uses on top of it, all locked in actions.lock. + includePlumberDefaults: true + trustedGithubActions: + - actions-ecosystem/action-regex-match + - amannn/action-semantic-pull-request + - crazy-max/ghaction-github-labeler + - securego/gosec diff --git a/README.md b/README.md index e9c9aa977..a4086d3d4 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Release](https://img.shields.io/github/v/release/linode/linodego)](https://github.com/linode/linodego/releases/latest) [![GoDoc](https://godoc.org/github.com/linode/linodego/v2?status.svg)](https://godoc.org/github.com/linode/linodego/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/linode/linodego/v2)](https://goreportcard.com/report/github.com/linode/linodego/v2) +[![Plumber Score](https://score.getplumber.io/github.com/linode/linodego.svg)](https://score.getplumber.io/github.com/linode/linodego) Go client for [Linode REST v4 API](https://techdocs.akamai.com/linode-api/reference/api)