fix(repo-standard): one reusable workflow = one authority ceiling (#55) - #57
Merged
Merged
Conversation
repo-standard.yml @ #54 raised its permission floor above `contents: read` (sbom needs `contents: write`, scorecard needs `actions: read`). GitHub validates a called reusable workflow's permission requests as the UNION of all its jobs, at load time, before any `if:` — so every caller, even a read-only spell/security PR run, had to grant the superset or hit a zero-jobs `startup_failure`. That is why #54 could not start and why conformance#19 is blocked. Restore one reusable workflow = one authority ceiling: - repo-standard.yml — stays `contents: read` (osv, dependency-review, spell, test, descriptor); drops the scorecard/sbom jobs + inputs - repo-scorecard.yml — `contents: read` + `actions: read` (scorecard) - repo-release.yml — `contents: write` (sbom); adds an `upload-release-assets` input so callers can take the SBOM artifact without a release upload Callers opt into the elevated ceilings with dedicated, event-gated jobs, so a PR run never instantiates write authority. Add repo-standard-selftest.yml: calls each reusable workflow at its intended ceiling. GitHub validates the permission union at load time, so a future revision that raises a floor fails here, pre-merge, instead of in every downstream repo — the self-test guard #55/#56 identified as missing. It also doubles as the reference caller template. Fixes #55. Closes #56. Unblocks conformance#19. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
bdelanghe
marked this pull request as ready for review
July 8, 2026 23:26
This was referenced Jul 8, 2026
bdelanghe
added a commit
that referenced
this pull request
Jul 8, 2026
The flake repos (door-concierge/keeper/net/peercred/scout, claude-box, facilities) each carry a near-identical flakehub-publish.yml — checkout → nix-installer → flakehub-push. Factor it into one reusable workflow so callers just configure rolling/visibility (derive, not copy). Authority ceiling `id-token: write` (FlakeHub OIDC) + `contents: read` — a ceiling distinct from repo-standard.yml's, so per one-workflow-one-ceiling (#57) it is its own file. Pins bumped to the org standard where they'd drifted (checkout v4→v7; nix-installer moving `# main` → a fixed SHA). Retires 2 outer-set actions (nix-installer-action, flakehub-push) from ~7 repos' direct usage, folding them into the canonical set. Caller migration is a follow-up (per-repo thin caller); this PR only adds the reusable workflow. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
repo-standard.yml@ #54 (60745f9b) raised its permission floor abovecontents: read: thesbomjob declarescontents: writeandscorecarddeclaresactions: read. GitHub validates a called reusable workflow's permission requests as the union of all its jobs, at load time, before anyif:— so every caller, even a read-only spell/security PR run, had to grant the superset or get a zero-jobsstartup_failure. That's the #55 root cause (confirmed: orgallowed_actions: "all", so it was never the Actions allowlist), and why conformance#19 is blocked.Fix — one reusable workflow = one authority ceiling
repo-standard.ymlcontents: readrepo-scorecard.ymlcontents: read+actions: readrepo-release.ymlcontents: writeupload-release-assetsinput)Because the caller grant is validated as the union of the called workflow's jobs, each distinct ceiling must be its own file — otherwise a scorecard-only caller (scorecard was
default: true, i.e. ~every repo) would be forced to grantcontents: write. Callers now opt into the elevated ceilings with dedicated, event-gated jobs, so a PR run never instantiates write authority.Regression guard (closes #56)
repo-standard-selftest.ymlcalls each reusable workflow at its intended ceiling. GitHub validates the permission union at load time, so a future revision that raises a floor fails here, pre-merge, instead of in every downstream repo — the self-test this repo lacked (which is how #54 shipped green). It also doubles as the reference caller template.Caller migration (separate PR)
Callers that used
scorecard: true/sbom: trueinputs move those to dedicated jobs callingrepo-scorecard.yml/repo-release.yml. Tracked for conformance in conformance#19; other repos on the old pin are unaffected until they bump.PR checklist
.githubreusable-workflow split only; caller adoption (conformance#19) is separatecontents: readfloor (evidence in repo-standard.yml @ #54 fails caller startup: scorecard/sbom actions not in the org Actions allowlist #55)Fixes #55. Closes #56. Unblocks conformance#19.
🤖 Generated with Claude Code