Skip to content

docs: caller permissions are a requirement, not a minimum - #3

Merged
RobFaustLZ merged 1 commit into
mainfrom
fix/node-build-permissions
Jul 28, 2026
Merged

docs: caller permissions are a requirement, not a minimum#3
RobFaustLZ merged 1 commit into
mainfrom
fix/node-build-permissions

Conversation

@FaustClaw

Copy link
Copy Markdown

Documentation fix, found by three real callers failing during the fan-out.

What broke

cf-analytics-pipeline, cf-queue-consumer and cf-api-gateway all granted contents: read — which is what this README told them was enough when run-codecov is false. All three died with startup_failure before a single job started. The Actions UI is unhelpful here: it says only "This run likely failed because of a workflow file issue." web-app-react passed, because it sets run-codecov: true and therefore granted id-token: write.

The rule is that a called workflow's permissions must be equal to or more restrictive than the caller's. node-build.yml declares id-token: write unconditionally, so every caller must grant it — regardless of run-codecov.

Why not just remove the declaration

That was my first fix, and it's wrong. I pushed it to a branch and pointed a real caller at it. The run started, then actions/checkout failed:

GITHUB_TOKEN Permissions
Metadata: read
remote: Repository not found.
fatal: repository 'https://github.com/labelzoom/labelzoom-cf-queue-consumer/' not found

Omitting permissions: in a called workflow does not inherit the caller's grant — the job drops to Metadata: read. So the block can't be deleted, and since a static block can't vary with an input, declaring the maximum and requiring callers to match is the only design that works.

Declaring only contents: read was the other option, and it's worse: it would silently cap Codecov callers and stop their coverage uploads, with fail_ci_if_error: false hiding the breakage.

Changes

  • The workflow table now says node-build.yml requires contents: read and id-token: write, always.
  • A new section records both failure modes, including the exact symptoms, so the next person recognises them.
  • An inline comment in node-build.yml explains why the declaration is unconditional and why neither alternative works.

No behaviour change — node-build.yml's permissions are byte-identical to what's live at @v1. This does not need a release to unblock anything; the three affected callers are being fixed to grant id-token: write against the current @v1.

🤖 Generated with Claude Code

The README said node-build.yml needs id-token: write only 'if run-codecov'.
Wrong, and it cost three repos a red build: a called workflow's permissions must
be equal to or MORE restrictive than the caller's, so the callee's unconditional
id-token: write declaration means EVERY caller must grant it or the run dies with
startup_failure before any job starts.

Also documents the other half, found while trying to fix it the other way: if the
reusable workflow omits its permissions block, the job does not inherit the
caller's grant -- it drops to  and even checkout fails with
'Repository not found'. So the block cannot simply be deleted, and a static block
cannot vary with an input. Declaring the maximum and requiring callers to match is
the only design that works.

Co-Authored-By: Claude <noreply@anthropic.com>
@FaustClaw
FaustClaw requested a review from a team as a code owner July 28, 2026 05:06
@RobFaustLZ
RobFaustLZ merged commit ea6421e into main Jul 28, 2026
1 check passed
@RobFaustLZ
RobFaustLZ deleted the fix/node-build-permissions branch July 28, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants