Security Finding
Severity: high
Type: permission-issue / credential exposure
Cluster: .github/workflows/{import-architectures,refresh-community-people,deploy-gh-pages,pdf}.yml — the actions/checkout step only.
Four of the six workflows call actions/checkout without persist-credentials: false. With the default (true), checkout writes the job's GITHUB_TOKEN into .git/config as
[http "https://github.com/"]
extraheader = AUTHORIZATION: basic <base64 of x-access-token:ghs_...>
That file stays on disk for the rest of the job and is readable by any code the job subsequently executes.
The two worst cases run with a workflow-level permissions: contents: write + pull-requests: write:
import-architectures.yml — after checkout it runs npm ci, npm run import:architectures (which pulls and processes untrusted content from cncf/architecture), and npm run build.
refresh-community-people.yml — after checkout it runs npm ci, npm run fetch:community-people, npm run build.
So a malicious npm lifecycle script in any direct or transitive dependency (or any code path reachable from the imported third-party architecture content) can read a write-scoped repository token straight out of .git/config and push to main.
pdf.yml is the same shape with contents: write plus an unpinned npx docusaurus-prince-pdf. deploy-gh-pages.yml is lower impact (contents: read) but should be consistent.
This repository already knows the right pattern: ci.yml (line 18) and create-milestones.yml (line 23) both set persist-credentials: false. These four were simply missed.
Impact
Any code executing in these jobs — an npm postinstall in a compromised transitive dependency, or a build-time code path reached from imported cncf/architecture content — can exfiltrate a contents: write / pull-requests: write GITHUB_TOKEN and use it to push commits to main, tamper with the published site, or open/modify pull requests. No token is needed in .git/config for any of these jobs to work (see verification below), so this is pure unnecessary exposure.
Recommendation
Nothing in these four jobs uses the persisted git credential:
import-architectures.yml / refresh-community-people.yml push via peter-evans/create-pull-request@v7, which authenticates with its own token input (default ${{ github.token }}) for both the branch push and the PR creation — branch-token defaults to token. It does not read .git/config.
pdf.yml uploads via gh release upload, which uses the GITHUB_TOKEN env var.
deploy-gh-pages.yml performs no git write at all.
Apply these four edits verbatim.
1. .github/workflows/import-architectures.yml (line 19)
Replace:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
2. .github/workflows/refresh-community-people.yml (line 19)
Replace:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
3. .github/workflows/deploy-gh-pages.yml (lines 25-26)
Replace:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
persist-credentials: false
4. .github/workflows/pdf.yml (line 13)
Replace:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
persist-credentials: false
Completion criteria
Why there is no pull request attached to this issue
Every line of this fix lives under .github/workflows/. The agent that filed this finding holds a GitHub App token minted at the contributor tier, which does not carry the Workflows permission, so GitHub rejects any push whose diff touches .github/workflows/** server-side. This is a hard ceiling, not a review decision: this change needs a human maintainer, or an agent with workflow-write scope, to land it. No part of the fix lives outside .github/workflows/, so there is no partial PR to open either.
Scope note
This issue claims only the actions/checkout step in the four named workflow files. It does not overlap open security work on package.json overrides, .github/dependabot.yml, scripts/import-architectures.mjs, scripts/validate-architectures.mjs, or scripts/validate-architecture-assets.mjs. It is also distinct from #39 (Prince tarball integrity, now verified with sha256sum -c on main), #123 (docusaurus-prince-pdf Node 22 incompatibility) and #188 (missing release tag 0.1), none of which concern credential persistence.
— hive: agent=sec-check backend=copilot model=claude-opus-5
Security Finding
Severity: high
Type: permission-issue / credential exposure
Cluster:
.github/workflows/{import-architectures,refresh-community-people,deploy-gh-pages,pdf}.yml— theactions/checkoutstep only.Four of the six workflows call
actions/checkoutwithoutpersist-credentials: false. With the default (true), checkout writes the job'sGITHUB_TOKENinto.git/configasThat file stays on disk for the rest of the job and is readable by any code the job subsequently executes.
The two worst cases run with a workflow-level
permissions: contents: write+pull-requests: write:import-architectures.yml— after checkout it runsnpm ci,npm run import:architectures(which pulls and processes untrusted content fromcncf/architecture), andnpm run build.refresh-community-people.yml— after checkout it runsnpm ci,npm run fetch:community-people,npm run build.So a malicious npm lifecycle script in any direct or transitive dependency (or any code path reachable from the imported third-party architecture content) can read a write-scoped repository token straight out of
.git/configand push tomain.pdf.ymlis the same shape withcontents: writeplus an unpinnednpx docusaurus-prince-pdf.deploy-gh-pages.ymlis lower impact (contents: read) but should be consistent.This repository already knows the right pattern:
ci.yml(line 18) andcreate-milestones.yml(line 23) both setpersist-credentials: false. These four were simply missed.Impact
Any code executing in these jobs — an npm postinstall in a compromised transitive dependency, or a build-time code path reached from imported
cncf/architecturecontent — can exfiltrate acontents: write/pull-requests: writeGITHUB_TOKENand use it to push commits tomain, tamper with the published site, or open/modify pull requests. No token is needed in.git/configfor any of these jobs to work (see verification below), so this is pure unnecessary exposure.Recommendation
Nothing in these four jobs uses the persisted git credential:
import-architectures.yml/refresh-community-people.ymlpush viapeter-evans/create-pull-request@v7, which authenticates with its owntokeninput (default${{ github.token }}) for both the branch push and the PR creation —branch-tokendefaults totoken. It does not read.git/config.pdf.ymluploads viagh release upload, which uses theGITHUB_TOKENenv var.deploy-gh-pages.ymlperforms no git write at all.Apply these four edits verbatim.
1.
.github/workflows/import-architectures.yml(line 19)Replace:
with:
2.
.github/workflows/refresh-community-people.yml(line 19)Replace:
with:
3.
.github/workflows/deploy-gh-pages.yml(lines 25-26)Replace:
with:
4.
.github/workflows/pdf.yml(line 13)Replace:
with:
Completion criteria
.github/workflows/import-architectures.ymlcheckout setspersist-credentials: false.github/workflows/refresh-community-people.ymlcheckout setspersist-credentials: false.github/workflows/deploy-gh-pages.ymlcheckout setspersist-credentials: false.github/workflows/pdf.ymlcheckout setspersist-credentials: falseWhy there is no pull request attached to this issue
Every line of this fix lives under
.github/workflows/. The agent that filed this finding holds a GitHub App token minted at thecontributortier, which does not carry the Workflows permission, so GitHub rejects any push whose diff touches.github/workflows/**server-side. This is a hard ceiling, not a review decision: this change needs a human maintainer, or an agent with workflow-write scope, to land it. No part of the fix lives outside.github/workflows/, so there is no partial PR to open either.Scope note
This issue claims only the
actions/checkoutstep in the four named workflow files. It does not overlap open security work onpackage.jsonoverrides,.github/dependabot.yml,scripts/import-architectures.mjs,scripts/validate-architectures.mjs, orscripts/validate-architecture-assets.mjs. It is also distinct from #39 (Prince tarball integrity, now verified withsha256sum -con main), #123 (docusaurus-prince-pdfNode 22 incompatibility) and #188 (missing release tag0.1), none of which concern credential persistence.— hive: agent=sec-check backend=copilot model=claude-opus-5