Skip to content

chore(ci): scope the tap App token to contents + pull-requests - #514

Merged
Data-Wise merged 1 commit into
devfrom
feature/tighten-tap-token
Sep 5, 2026
Merged

Data-Wise merged 1 commit into
devfrom
feature/tighten-tap-token

Conversation

@Data-Wise

Copy link
Copy Markdown
Owner

What

homebrew-release.yml mints its tap credential with no permission-* inputs:

uses: actions/create-github-app-token@v3
with:
  app-id: ${{ secrets.APP_ID }}
  private-key: ${{ secrets.APP_PRIVATE_KEY }}
  owner: Data-Wise
  repositories: homebrew-tap

Omitting them means the minted token inherits every permission the data-wise-homebrew-automation installation holds on homebrew-tap, for the whole job — a job that runs sed, git and gh against a live credential. This declares the two it actually uses.

Permission Why
contents: write commit + push the formula edit
pull-requests: write open and auto-merge the bump PR (added by #499)

Both are known-granted, not guessed

The App has authored 7 PRs on the tap (#215, #214, #213, #212, #210, #209, #207) and merged its own — #212 and #210 both show mergedBy = app/data-wise-homebrew-automation, which requires pull-requests: write. The formula pushes prove contents: write.

Risk

No behavior change intended. create-github-app-token validates requested permissions against the installation and fails at mint time if one is not granted, so a mismatch surfaces immediately and loudly rather than silently degrading.

Worth stating plainly: this ships before the next release, so that release is its first live exercise — same as #499. If the mint fails, the fix is to drop these two lines.

Verification

  • actionlint — 2 SC2086 infos before, 2 after: identical, pre-existing, and in a different step (line 32). Nothing introduced.
  • YAML parses; both keys land in the app-token step's with: block:
step: Mint GitHub App token (for cross-repo push to homebrew-tap)
  owner = Data-Wise
  repositories = homebrew-tap
  permission-contents = write
  permission-pull-requests = write

Workflow-only change; no runtime code touched.

create-github-app-token was called with no permission-* inputs, so the
minted token inherited EVERY permission the data-wise-homebrew-automation
installation holds on homebrew-tap, for the duration of the job — a job
that runs sed, git and gh against a live credential.

The step needs exactly two things: commit and push the formula edit
(contents: write), and open then auto-merge the bump PR
(pull-requests: write) — the latter added by #499.

Both are known-granted, not guessed: the App has authored 7 PRs on the tap
(#215, #214, #213, #212, #210, #209, #207) and merged its own (#212, #210
show mergedBy = app/data-wise-homebrew-automation), which requires
pull-requests: write; the formula pushes require contents: write.

Least privilege on an existing credential — no behaviour change intended.
create-github-app-token fails at mint time if a requested permission is not
granted, so a mismatch surfaces immediately rather than silently.

Verified: actionlint reports the same 2 pre-existing SC2086 infos before
and after (different step, not introduced here); YAML parses and both keys
land in the app-token step's with: block.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Data-Wise
Data-Wise merged commit 2a78bb3 into dev Sep 5, 2026
3 checks passed
@Data-Wise
Data-Wise deleted the feature/tighten-tap-token branch September 5, 2026 01:59
Data-Wise added a commit that referenced this pull request Sep 5, 2026
- Add target-branch: dev to github-actions block. Without it, dependabot
  derives the base from the repo default (main) and resets it on every
  rebase, so a manual PR retarget can never stick (observed on #503, #512).
- Drop the npm package-ecosystem block entirely. package.json has no
  runtime dependencies -- only 3 devDependencies (husky, lint-staged,
  prettier) that never reach a user, since flow-cli ships as zsh through
  Homebrew. Of the last 16 npm dependabot PRs, 9 were closed unmerged and
  only 6 merged, each costing a full CI run (ZSH Plugin Tests ~7min).
  github-actions updates merged 3/3 and cover real security surface (e.g.
  #444 bumped actions/create-github-app-token, later hardened by #514).
- Bump prettier 3.9.4 -> 3.9.6 by hand (same version #503 proposed),
  superseding #503 -- closed as no longer needed.

Verified: prettier --check against this branch and against origin/dev
produce identical pre-existing warnings/errors (archive docs, test
fixtures) -- nothing newly introduced by this change.
Data-Wise added a commit that referenced this pull request Sep 5, 2026
Version bump for the 5 commits merged to dev since 7.17.1: 2 fixes
(#513 PATH, #499 tap-push GH006), 3 CI/deps changes (#512, #514, #515).
No feat commits -- patch bump.

- package.json, package-lock.json, flow.plugin.zsh (FLOW_VERSION),
  CLAUDE.md, man/man1/*.1 (.TH version line) via scripts/release.sh
- CHANGELOG.md + docs/CHANGELOG.md: new 7.17.2 entry (mirrored, per the
  project's dual-changelog convention)
- docs/index.md: footer version stamp only. The "What's New in
  v7.17.1" banner is left as-is -- it describes actual 7.17.1
  user-facing features, and 7.17.2 has none to add (pure CI/infra).

Test-run side effects (.STATUS wins/streak counters, a test fixture's
timestamp) surfaced as unrelated dirty files from running
./tests/run-all.sh and were excluded from this commit.
@Data-Wise Data-Wise mentioned this pull request Sep 5, 2026
Data-Wise added a commit that referenced this pull request Sep 5, 2026
.STATUS had not been touched since 2026-07-07 (f740eb5): the header still
read Phase: Released (v7.16.0) while v7.17.0, v7.17.1 and v7.17.2 had all
shipped, and Focus: held the literal string "--help" -- a bad write, not a
focus.

- Header: Phase -> Released (v7.17.2); Focus -> a real one-line focus.
- Added four session entries reconstructed from CHANGELOG.md, the merged PR
  bodies (#505, #506, #509, #513, #499, #514, #515) and the release tags:
  v7.17.0 (teach deploy safety + CI coverage), v7.17.1 (alias-proof
  pipelines), v7.17.2 (CI hardening + PATH fix), plus the 2026-07-08..07-19
  housekeeping commits and a session entry for this resync itself.
- Demoted the stale "Current Session (2026-07-07)" and two older headings
  that had been left as "Current Session" against the file's own convention.
- Test baseline refreshed from evidence rather than carried forward:
  84 passed / 0 failed / 0 timeout / 1 skipped across 85 registered suites,
  per CI run 33946019980 on dev.
- Next Action re-verified against repo state: added stale-issue triage
  (#487/#488/#489), the PR #500 rebase decision, .gitignore for
  .token-optimizer, and the advisory markdown-lint backlog.

Verified: scripts/check-status.zsh clean on the updated file (validator
confirmed non-vacuous via a planted "Progress: banana" defect, which it
caught); _flow_status_field reads all four header fields correctly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant