Skip to content

ci(KNO-16687): harden GitHub Actions workflows - #1109

Merged
cjbell merged 3 commits into
mainfrom
cjbell-kno-16687-secure-github-actions-b360
Nov 6, 2026
Merged

cjbell merged 3 commits into
mainfrom
cjbell-kno-16687-secure-github-actions-b360

Conversation

@cjbell

@cjbell cjbell commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Description

Hardens this repo's GitHub Actions, following the guidance linked from KNO-16655. That guidance covers four things: pin every action to a full SHA from the action's own repo, stop run: steps from pulling unpinned code, declare least-privilege permissions:, and lint so pins can't regress. Tracked in KNO-16687.

Every action here was already SHA-pinned. Each pin was checked with git ls-remote --tags and zizmor's online impostor-commit audit, and each one matches a release tag in the action's own repo. This PR fixes the remaining gaps.

Token permissions

  • release.yml had no permissions: block. It now has contents: read. Checkout, the prerelease-exit push, and changesets/action all use KNOCK_ENG_BOT_GITHUB_TOKEN. changesets/action v1.8.0 prefers the GITHUB_TOKEN env var over its github-token input, so it never uses the job token.
  • dependabot-changeset.yml drops from contents: write + pull-requests: read to contents: read. The gh lookup, the PR checkout, and the push all use the bot token.

Unpinned or untrusted code

  • The Expo native build pins eas-cli to 27.1.0 instead of latest. That's the newest release past a 7-day cooldown.
  • The integration workflow installs with --immutable. Its secrets move from job-level env to the test step, so dependency install scripts no longer see them.
  • The Dependabot changeset job checks github.event.pull_request.user.login instead of the spoofable github.actor.

Credentials and injection

  • persist-credentials: false is set on every checkout that doesn't push. The release checkout and the Dependabot PR-branch checkout keep the bot token because later steps push with it. Each has an inline zizmor: ignore[artipacked] explaining why.
  • Step outputs and the matrix value reach the shell through env: instead of ${{ }} interpolation. The pre.json guard uses jq --arg.

Keeping it that way

  • Dependabot now updates github-actions, with a 7-day cooldown, grouped into one PR.
  • A new GitHub Actions Security workflow runs zizmor 1.31.1 via zizmor-action v0.8.0 on changes under .github/. .github/zizmor.yml requires a full SHA for every action, including actions/*, which zizmor allows on tags by default. secrets-outside-env is disabled until secrets move into environments.

Follow-ups that need repo or org settings

  • Set the default workflow token permissions to read-only.
  • Require SHA pinning in the org Actions policy, and turn on workflow lockfiles for actions nested inside third-party actions.
  • Move NPM_TOKEN and KNOCK_ENG_BOT_GITHUB_TOKEN into a protected release environment.
  • Make the zizmor check a required status check.

Todos

  • Watch the next Release and Dependabot Changeset runs after merge. The permission changes only take effect on push to main and on Dependabot PRs, so this PR's CI can't exercise them.

Checklist

  • Tests have been added for new features or major refactors to existing features. The new zizmor workflow is the check. Locally, zizmor went from 33 findings (auditor persona) to none in the regular persona CI uses. A temporary workflow with actions/checkout@v4, dorny/paths-filter@v3, and a ${{ github.event.pull_request.title }} injection fails it with exit code 14. actionlint 1.7.7 is clean.
Open in Web Open in Cursor 

cursoragent and others added 3 commits November 6, 2026 15:29
- Declare read-only permissions in release.yml and drop the unused
  write scope from dependabot-changeset.yml (both use the bot token).
- Check the PR author instead of the spoofable github.actor.
- Pin eas-cli instead of installing latest.
- Install integration deps with --immutable and scope the integration
  secrets to the test step.
- Don't persist checkout credentials unless the job pushes.
- Pass step outputs and matrix values to scripts through env.

Co-authored-by: Chris Bell <chris@cjbell.co>
Co-authored-by: Chris Bell <chris@cjbell.co>
@vercel

vercel Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
javascript-ms-teams-connect-example Ready Ready Preview Nov 6, 2026 3:31pm UTC
javascript-nextjs-example Ready Ready Preview Nov 6, 2026 3:31pm UTC
javascript-slack-connect-example Ready Ready Preview Nov 6, 2026 3:31pm UTC
javascript-slack-kit-example Ready Ready Preview Nov 6, 2026 3:31pm UTC

Request Review

@linear-code

linear-code Bot commented Nov 6, 2026

Copy link
Copy Markdown

KNO-16687

@changeset-bot

changeset-bot Bot commented Nov 6, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: d7c189b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cursor
cursor Bot requested review from kylemcd and mattmikolay November 6, 2026 15:29

@cursor cursor 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.

Left a non-blocking comment: this GitHub Actions hardening change is not a docs, dependency, or auto-release PR, so it is not auto-approved. Human review is needed; kylemcd and mattmikolay were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: SDK approver

@cursor cursor 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.

Left a non-blocking comment: this is GitHub Actions hardening, not a dependency update, so it is outside this agent's approval criteria. Human review is needed, and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Depdency updates (control, switchboard, CLI, javascript, telegraph)

@codecov

codecov Bot commented Nov 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.48%. Comparing base (48996e1) to head (d7c189b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1109   +/-   ##
=======================================
  Coverage   78.48%   78.48%           
=======================================
  Files         140      140           
  Lines        4508     4508           
  Branches     1314     1314           
=======================================
  Hits         3538     3538           
  Misses        873      873           
  Partials       97       97           

@cjbell
cjbell enabled auto-merge (squash) November 6, 2026 16:42
Comment on lines -111 to +121
yarn config set npmAuthToken $NPM_TOKEN
yarn config set npmAuthToken "$NPM_TOKEN"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

was this broken? 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no, but doing it in quotes means it can't escape values into the command

@cjbell
cjbell merged commit 92ad6b6 into main Nov 6, 2026
16 checks passed
@cjbell
cjbell deleted the cjbell-kno-16687-secure-github-actions-b360 branch November 6, 2026 16:56

This branch was successfully deployed

4 active deployments
Preview – javascript-nextjs-example — d7c189ba Deployed Nov 6, 2026 by vercel[bot]
Preview – javascript-ms-teams-connect-example — d7c189ba Deployed Nov 6, 2026 by vercel[bot]
Preview – javascript-slack-kit-example — d7c189ba Deployed Nov 6, 2026 by vercel[bot]
Preview – javascript-slack-connect-example — d7c189ba Deployed Nov 6, 2026 by vercel[bot]
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.

3 participants