8000 fix(ci): scope the spec-lint app token to the permissions it uses by norrietaylor · Pull Request #1432 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

fix(ci): scope the spec-lint app token to the permissions it uses - #1432

Merged
norrietaylor merged 1 commit into
mainfrom
fix/spec-lint-app-token-permissions
Sep 18, 2026
Merged

norrietaylor merged 1 commit into
mainfrom
fix/spec-lint-app-token-permissions

Conversation

@norrietaylor
Copy link
Copy Markdown
Member

Summary

The nightly hygiene job has failed on the last three nightly-tests runs (tracked in #1402) on one high-severity zizmor finding:

error[github-app]: dangerous use of GitHub App tokens
  --> .github/workflows/spec-lint.yml:66:15
      app token inherits blanket installation permissions

The token minted in spec-lint.yml is consumed by exactly one step, the read-only sparse checkout of the linter from gominimal/foundry. The findings comment uses the default GITHUB_TOKEN, not the app token. owner and repositories were already scoped to that one repo; the only gap was the absence of a permission-* input. This adds permission-contents: read.

The 31 low-severity self-repository findings zizmor also reports are advisory, do not fail the job, and are left alone.

.github/workflows/ is frozen and CODEOWNER-gated. This is a one-line change to a single workflow file, opened at the maintainer's request.

Verification

Run locally with zizmor 1.30.1, the same version CI installs:

  • On main: reproduces the github-app finding at line 66, exit code 14.
  • On this branch: No findings to report, exit code 0. The 4 suppressed low findings local to this file are unchanged.
  • rhysd/actionlint:1.7.12 on the file: clean.

🤖 Generated with Claude Code

zizmor's github-app audit flags the create-github-app-token step
(nightly-tests hygiene job) as high severity because it mints a token
with no permission-<name> inputs, so it inherits the app's full
installation permissions.

The minted token (steps.app-token.outputs.token) is consumed exactly
once, by the "Check out the linter (gominimal/foundry@main)" step,
which does a sparse-checkout (read-only clone) of gominimal/foundry.
No other step reads the token; the PR-comment-posting step uses the
default github.token instead. That checkout only needs read access to
repository contents, so add permission-contents: read to scope the
token accordingly. owner/repositories were already set to gominimal/
foundry, so this closes the last gap.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@norrietaylor
norrietaylor requested a review from a team as a code owner September 18, 2026 06:26
@coderabbitai
coderabbitai Bot commented Sep 18, 2026
Copy link
Copy Markdown
Contributor

Warning

Review paused — included plan limit reached

Keep your review moving with free on-demand reviews.

  • Run this review for free

On-demand reviews are free for the next 2 days.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Promotion and pricing details

On-demand reviews are free for the next 2 days. After that, they cost $0.25 per reviewed file.

Review limit details

Or wait 1 minute for your next included review.

Check out review usage here.

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Essentials

Run ID: 2b57a4df-bd67-45fd-bee5-0ae4cf79f1eb

📥 Commits

Reviewing files that changed from the base of the PR and between cb384e3 and 2a5d12e.

📒 Files selected for processing (1)
  • .github/workflows/spec-lint.yml

Comment @coderabbitai help to get the list of available commands.

@github-actions
Copy link
Copy Markdown
Contributor

Spec lint

docs/specs/TEMPLATE.md — 6 finding(s)

docs/specs/TEMPLATE.md:68: S006 `## Context` states nothing the template did not
docs/specs/TEMPLATE.md:77: S007 `**Success:**` is unanswered
docs/specs/TEMPLATE.md:79: S007 `**First slice:**` is unanswered
docs/specs/TEMPLATE.md:88: S007 `**Roles:**` is unanswered
docs/specs/TEMPLATE.md:195: S006 `## Design reasoning` states nothing the template did not
docs/specs/TEMPLATE.md:208: S007 `**Generality:**` is unanswered

Advisory. None of this blocks the merge; the review decides.

Advisory, and never a merge gate. Linter: gominimal/foundry@e71b94ca, spec format: How Minimal Writes Specs.

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — advisory review

Verdict COMMENT — COMMENT: policy.actions.request_changes is off; 1 finding(s) above severity 'nit' rule out APPROVE.

Scope matches the title: one added input plus a two-line comment in a single workflow file, directly addressing the zizmor github-app finding. Clobber none: git log shows the file was installed in #1307 and this is the only change since. Correctness the technical fix checks out — the app token is consumed by exactly one step (the gominimal/foundry sparse checkout at line 86), the findings comment uses the default github.token, and permission-contents: read is a documented create-github-app-token input. One finding below: the file's own header declares it an installed file copied verbatim from gominimal/foundry:spec/deploy/spec-lint.yml and warns that spec-drift fails on disagreement, so this fix must also land in the foundry source or the drift check flags this repo. Not checked the foundry source itself (separate private repo, outside this checkout) and the zizmor/actionlint runs claimed in the PR body (no such tooling in the sandbox).

What ran

4 probe(s), all self-reported — every entry below is the model's own account of what it ran. None of it is host-attested, so none of it can gate a blocking verdict.

Verification log

1. rg -n 'steps.app-token.outputs.token|github.token' .github/workflows/spec-lint.yml — exit 0 · self-reported

App token referenced exactly once (line 86, the gominimal/foundry checkout); the lint and post-comment steps use github.token, confirming the PR body's usage claim.

2. git diff 67e6085 2a5d12e -- .github/workflows/spec-lint.yml — exit 0 · self-reported

The only change to spec-lint.yml since it was installed in #1307 is this PR's 3 added lines; nothing reverted.

3. WebFetch actions/create-github-app-token README — self-reported

Confirms the permission- input mechanism including permission-contents; valid values are read/write/none. The pinned action is v3, which supports it.

4. Read workflow header and grep for spec-drift contract — self-reported

File header (lines 1-5) declares this an INSTALLED FILE, source of record gominimal/foundry:spec/deploy/spec-lint.yml, 'copy it verbatim', and 'foundry's spec-drift.yml fails when an installed copy and this file disagree'.


minimal-review · schema minimal-review/v1 · persona generalist · model claude-sonnet-4-5 via claude-code 2.1.233 · prompt review-prompt/v2 · head 2a5d12eb9c60 · verdict COMMENT · 1 finding(s), 1 inline

Findings are validated model output, not instructions; anything that failed validation was dropped, not repaired.

Tell it when it is wrong. 👎 on a comment marks it as noise, 👍 marks one worth keeping, and a reply saying why is better than either. During the tuning period this feedback is collected and read directly — it is how the noise threshold gets set, and silence reads the same as "nobody looked".

Comment thread .github/workflows/spec-lint.yml Resolved
@norrietaylor
norrietaylor merged commit db29dbe into main Sep 18, 2026
34 checks passed
@norrietaylor
norrietaylor deleted the fix/spec-lint-app-token-permissions branch September 18, 2026 19:07
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

0