Standard: CI Service Secrets

Three CI integrations need a per-repo GitHub Actions secret before their workflows can run. They're the values that make the badges, the coverage gate in testing, and the Scorecard signal in supply-chain-hardening actually light up rather than render "unknown" forever. This standard names the three secrets, records where each value comes from, and provides the tool that provisions them so nobody has to hunt for the links again.

Canonical, project-agnostic standard (the version other repos copy). It provisions the secrets the services in badges, testing, and supply-chain-hardening depend on — it does not introduce the services themselves. Provisioning tool: ../tools/repo-tokens.ps1.

The secrets

SecretServiceWhat it unlocksWhere to get the value
SONAR_TOKENSonarCloudQuality-gate + tech-debt analysis (and the Sonar badges)sonarcloud.io/account/security — Account › Security › Generate; or the project's Administration › Analysis Method
CODECOV_TOKENCodecovCoverage upload from CI (and the coverage badge)app.codecov.io/gh/1fairyfox — repo › Configuration › General › Repository Upload Token
SCORECARD_TOKENOpenSSF ScorecardBranch-protection read / results publish above the default token's reachgithub.com/settings/tokens/new — classic PAT, scopes public_repo (or repo) + read:org

All three are single-line tokens, set as repository secrets under the same name the workflows reference (secrets.SONAR_TOKEN, etc.). Scorecard's is a GitHub Personal Access Token, not a service key.

Provisioning them — the tool

Run hub/tools/repo-tokens.ps1 (the "fairyfox repo tokens" trigger). It prints the get-it link and a short how-to for each secret, then prompts for the value with the input concealed. The value is streamed to gh secret set … --body-file - over stdin and the plaintext copy is zeroed immediately — it never lands on disk, in the shell history, in a command-line argument, or in an AI transcript.

  • Blank + Enter skips a secret — nothing is sent to gh for it. Skip the ones a given repo doesn't use.
  • Target defaults to the current directory's repo (gh repo view); override with -Repo OWNER/NAME. -Only SONAR_TOKEN,CODECOV_TOKEN prompts a subset.
  • Requires an authenticated gh (gh auth login). It prints gh secret list at the end so you can confirm what's set.

Applicability

"Applicable" is the only filter, exactly as in badges: a repo provisions the secret for each service it actually wires. A repo with no SonarCloud project skips SONAR_TOKEN; a repo with no coverage upload skips CODECOV_TOKEN. A secret is required when — and only when — a workflow references it; an un-referenced secret is neither expected nor faked. (fairyfox.io itself, a Jekyll site, wires none of the three and is N/A across the board.)

Verify (is it being followed?)

The per-standard slice the compliance audit aggregates — report done/partial/missing:

Passes only when…How to check
Every secret a workflow references is set on the repogh secret list --repo OWNER/NAME, cross-checked against secrets.* uses in .github/workflows/
No workflow references a secret that isn't set (nothing renders "unknown"/unauthenticated)grep the workflows for secrets. and confirm each has a matching secret
The secret names match the canonical set (SONAR_TOKEN, CODECOV_TOKEN, SCORECARD_TOKEN)inspect the secret list and the workflow references
A repo wiring none of the three is a clean N/A, not a gapconfirm no secrets.{SONAR,CODECOV,SCORECARD}_TOKEN reference exists to satisfy