fix(gate): mount canary uses optional admin token, not an invalid GITHUB_TOKEN scope#25
Merged
Merged
Conversation
…t an invalid GITHUB_TOKEN scope The self-verifying required-mount canary declared `administration: read` in the workflow (and caller stub) permissions. `administration` is not a grantable GITHUB_TOKEN scope — declaring it makes the reusable-workflow YAML invalid, so the gate job dies at 0s and never emits a `gate / gate` status check. That broke the gate for every consumer wiring this kit (a downstream gauge PR sat blocked with no gate check at all). Fix: - Drop `administration: read` from the gate's top-level permissions and from the caller stub; keep `contents: read`. Both now declare only grantable scopes. - Route the canary's branch-protection read through an OPTIONAL `CI_KIT_TOKEN` secret (a fine-grained PAT / GitHub App installation token carrying repo Administration:read), forwarded by the caller's existing `secrets: inherit`. - Degrade-vs-strict: with no token the canary emits a warning and passes (the out-of-band Constable sweep + check-required-mount.sh remain the enforcement, so un-provisioned consumers are not bricked); with the token it runs the strict proof and refuses (exit 1) when the gate cannot prove it is required. - Tests: add a GITHUB_TOKEN permission allowlist + a regression guard that fails if any workflow/caller declares the non-grantable `administration` scope again (this guard goes red on the pre-fix tree), plus coverage of the optional-token wiring and the degrade path. Co-Authored-By: Claude Opus 4.8 (1M context) <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.
What & why
The self-verifying required-mount canary declared
administration: readin the reusable workflow'spermissions:block (and in the caller stub).administrationis not one of the scopes grantable to the automaticGITHUB_TOKEN— declaring it makes the reusable-workflow YAML invalid, so the gate job dies at 0s and never emits agate / gatestatus check. That silently broke the gate for consumers wiring this kit (a downstream gauge PR has been sitting blocked with no gate check at all).administrationis a valid permission for fine-grained PATs / GitHub Apps — just not forGITHUB_TOKEN. So the canary must read branch protection with a separate, optional token.The fix
administration: readremoved from the gate's top-levelpermissions:and fromtemplates/quality.caller.yml; both now declare only grantable scopes (contents: read).secrets.CI_KIT_TOKEN(a fine-grained PAT / GitHub App installation token carrying repo Administration: read), forwarded by the caller's existingsecrets: inherit.GH_TOKENfalls back togithub.tokenso the CLI always has a host token.CI_KIT_TOKEN: the canary emits a::warning::and passes — un-provisioned consumers are not bricked, and the out-of-band Constable sweep +check-required-mount.shremain the enforcement. With the token: it runs the strict proof and refuses (exit 1) when the gate cannot prove it is a required, non-bypassable check.Tests (the planted-violation goes red on
main)GITHUB_TOKENpermission allowlist test + a regression guard asserting no workflow/caller declaresadministrationagain — both fail on the pre-fix tree and pass here.test_workflows.py; the deterministic battery (ruff, ruff-format, mypy, complexipy, file-budget, import-contract) is green on this tree.Follow-ups (operator gates — not in this PR)
CI_KIT_TOKENorg/repo secret (admin:read PAT/App). Until then the leg degrades to a warning by design.🔒 Law-pending — open for the operator's gate; do not auto-merge.