Repository navigation
Stop ci-shared capping the pipelines' permissions - #21
Merged
matt-edmondson merged 1 commit intoSep 16, 2026
Merged
Conversation
The canary found this. ktsu-dev/Sorting#46 adopted ci.yml and the run failed at startup with no jobs: a called workflow cannot elevate above what its caller granted, and ci-shared.yml's workflow-level `permissions: contents: read` became the ceiling for every pipeline it dispatches. dotnet.yml's release job asks for `contents: write` and `packages: write`, which under that ceiling can never be satisfied, so the run died before a job existed to report it. Remove the workflow-level block so the caller's grant flows through, and give `detect` its own `contents: read` -- it only reads repository metadata. The caller template now grants the union the pipelines request: contents, packages and id-token, all write. That union is the real contract between a repository and the shared pipelines, so it is stated in the caller where it is granted rather than left to be discovered by a startup failure. This does not widen anything at runtime. dotnet.yml keeps its own `permissions: contents: read` default and its per-job overrides, exactly as it behaved as a standalone workflow; the difference is only that the ceiling above it is now high enough to permit them. What the canary did prove, before failing: the relative `./` reference inside ci-shared.yml resolves within ktsu-dev/.github. The run recorded 905bdc6 -- the same commit as ci-shared.yml, not the caller's repository -- which is the assumption the whole dispatcher rests on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RABe2NufFc9hwm94iB3Rf
matt-edmondson
pushed a commit
to ktsu-dev/Sorting
that referenced
this pull request
Sep 16, 2026
Two findings on this pull request, one root cause. The CI run ended in startup_failure with no jobs: a called workflow cannot elevate above what its caller granted, and neither this caller nor the dispatcher granted enough for dotnet.yml's release job, which asks for `contents: write` and `packages: write`. CodeQL flagged the same file for having no permissions block at all, which is the other half of it -- without one the caller silently takes the repository default, which is both unstated and, here, insufficient. Grant the union the shared pipelines request. The file stays byte-identical to the template published in ktsu-dev/.github's docs/shared-ci.md, so the fan-out remains a copy rather than a per-repository edit. This alone does not turn the run green: the dispatcher also caps its callees at `contents: read`, fixed in ktsu-dev/.github#21. The tag this repository resolves, @Release, still points at the version with that cap, so CI here stays red until #21 merges and the tag is re-promoted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RABe2NufFc9hwm94iB3Rf
matt-edmondson
deleted the
claude/dependabot-ci-workflow-rollout-fbrhdn
branch
September 16, 2026 09:40
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 the canary found
ktsu-dev/Sorting#46 adopted
ci.ymland the run endedstartup_failurewith zero jobs.A called workflow cannot elevate above what its caller granted, and
ci-shared.yml's workflow-levelpermissions: contents: readbecame the ceiling for every pipeline it dispatches.dotnet.yml'sreleasejob asks forcontents: writeandpackages: write, which under that ceiling can never be satisfied — so the run died before a job existed to report it.The permission surface the pipelines actually request:
dotnet.ymlreleasecontents: write,packages: writedotnet.ymlsecurityid-token: write,contents: writedotnet-private.ymlbuildcontents: write,packages: readdotnet-private.ymlwingetcontents: writedotnet-private.ymlsecurityid-token: write,contents: writeUnion:
contents: write,packages: write,id-token: write.The fix
ci-shared.ymldrops its workflow-levelpermissionsso the caller's grant flows through, anddetecttakescontents: readon its own — it only reads repository metadata.docs/shared-ci.mdnow grants that union. It is the real contract between a repository and the shared pipelines, so it belongs in the caller where it is granted, rather than being discovered through a startup failure.This widens nothing at runtime.
dotnet.ymlkeeps its ownpermissions: contents: readdefault and its per-job overrides, behaving exactly as it did standalone. The only difference is that the ceiling above it is now high enough to permit what it already asked for.What the canary proved before it failed
The run recorded its
referenced_workflowsas:The relative
./reference insideci-shared.ymlresolves withinktsu-dev/.github, at the same commit asci-shared.yml— not against the calling repository. That is the assumption the entire dispatcher rests on, it was the one thing the docs did not state for the nested case, and it is now settled by observation rather than inference. The@releasetag also resolved correctly on its first real use.After this merges
The
releasetag needs re-promoting to pick this up (Promote release, refmain), then Sorting#46 needs itsci.ymlupdated with thepermissionsblock and re-run.Testing
actionlint1.7.7 withshellcheckclean;markdownlint-cliclean.🤖 Generated with Claude Code
https://claude.ai/code/session_014RABe2NufFc9hwm94iB3Rf
Generated by Claude Code