From 8575413f0748eb3132569f5bd11368ccc1daf32a Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Mon, 7 Sep 2026 02:51:05 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=F0=9F=94=A7=EF=BC=9Astop?= =?UTF-8?q?=20the=20workflows=20from=20keeping=20the=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ported from OpenINF/.github, where this is part of bccd6d2. lint-and-test.yml named no permissions at all, so it inherited whatever the repository hands a workflow by default -- which for a repository that has not been narrowed is a write token, held for the length of an install and a lint run. Naming any permission drops the rest to none, so `contents: read` plus the `pull-requests: read` that paths-filter needs is the whole of what this workflow does. The filter stays. The reasoning that retired it in OpenINF/.github does not hold here: that suite reads files, while this one builds a site and starts a JVM, so what filtering buys there and here is not the same number. Separately, actions/checkout leaves its token in .git/config unless told not to. Nothing downstream of any of these four checkouts pushes, and no dependency is git-hosted, so the token is only sitting where `pnpm install` and everything after it could reach it. Wider than the change it is ported from, and deliberately so: the upstream repository has two of these workflows and this one has four. deploy.yml uploads an artifact and lets deploy-pages authenticate with its own id-token, and vendored-sync.yml talks to the API through GH_TOKEN rather than through git, so neither needs the credential either. Hardening two of four and leaving the other two would be harder to explain than doing all of them. Signed-off-by: Derek Lewis Assisted-by: Claude-Code:claude-opus-5 --- .github/workflows/deploy.yml | 3 +++ .github/workflows/lint-and-test.yml | 10 ++++++++++ .github/workflows/pull-request-policy.yml | 4 ++++ .github/workflows/vendored-sync.yml | 4 ++++ 4 files changed, 21 insertions(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f2e52791d..7a831c9c0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -26,6 +26,9 @@ jobs: - name: Check out project repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + # Nothing here pushes: the build uploads an artifact and + # deploy-pages authenticates with its own id-token. + persist-credentials: false # The docs pages date themselves from when git last touched them, # which a single-commit checkout cannot answer. fetch-depth: 0 diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index 9f49f338e..04f086081 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -10,6 +10,12 @@ on: branches: - live +# Stated, not inherited: paths-filter needs `pull-requests: read`, and naming +# any permission drops the rest to none. +permissions: + contents: read + pull-requests: read + jobs: lint_and_test: name: Lint and test @@ -21,6 +27,10 @@ jobs: # `verify.commits` compares against the base branch, which a # single-commit checkout does not contain. fetch-depth: 0 + # Otherwise the token stays in .git/config while `pnpm install` and + # the linters run. Nothing downstream needs it: no step pushes, and + # no dependency is git-hosted. + persist-credentials: false - name: Set up Node.js runtime uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: diff --git a/.github/workflows/pull-request-policy.yml b/.github/workflows/pull-request-policy.yml index 66b19cee9..bb1916996 100644 --- a/.github/workflows/pull-request-policy.yml +++ b/.github/workflows/pull-request-policy.yml @@ -29,6 +29,10 @@ jobs: steps: - name: Check out project repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + # Nothing here pushes, and a token left in .git/config is one more + # thing that could be picked up by something that should not have it. + persist-credentials: false - name: Set up Node.js runtime uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: diff --git a/.github/workflows/vendored-sync.yml b/.github/workflows/vendored-sync.yml index 10091c3af..5dd0a32a6 100644 --- a/.github/workflows/vendored-sync.yml +++ b/.github/workflows/vendored-sync.yml @@ -37,6 +37,10 @@ jobs: steps: - name: Check out project repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + # Nothing here pushes, and a token left in .git/config is one more + # thing that could be picked up by something that should not have it. + persist-credentials: false - name: Set up Node.js runtime uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: