Skip to content

CI: Pin the third-party actions by commit, scope the workflow tokens and drop persisted checkout credentials - #12315

Merged
JonnyBurger merged 4 commits into
remotion-dev:mainfrom
Totara-thib:ci-hardening
Oct 19, 2026
Merged

JonnyBurger merged 4 commits into
remotion-dev:mainfrom
Totara-thib:ci-hardening

Conversation

@Totara-thib

@Totara-thib Totara-thib commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Hello, three commits on the hand-written workflows, pullfrog.yml left as its header asks.

  • The 25 third-party action references move from tags to commit SHAs, the tag kept as a comment. ruby/setup-ruby@master is pinned to the v1.329.0 release. First-party actions stay on their tags.
  • push.yml and changelog.yml declare a read-only token and discord.yml none at all, it only calls a webhook under pull_request_target.
  • Thirteen checkouts stop persisting the token. The claude.yml and pullfrog.yml checkouts are untouched, those agents commit back.

Why: a tag is a movable pointer, and these jobs run on every pull request with the default token while changelog.yml holds the Discord token. The tj-actions incident (CVE-2025-30066) went through exactly that door.

There is no update bot here, a dependabot github-actions entry would keep the pins current, happy to add it. If the allowed-actions setting uses tag patterns, switch them to owner/action@* first, SHA refs do not match the tag form.

Found and fixed by Plumber's analysis, reviewed and submitted by me. I'm also a long time user of Remotion

A tag such as oven-sh/setup-bun@v2.1.2 is a movable pointer: whoever
can push to that repository decides what runs in these jobs. The 25
third-party references in the five hand-written workflows now point at
the commit the tag resolved to today, with the tag kept as a comment so
the version is still readable. ruby/setup-ruby@master was a branch, it
is pinned to the v1.329.0 release. First-party actions/* stay on their
tags. pullfrog.yml is left as its header asks.
…h the token

push.yml, changelog.yml and discord.yml had no permissions block, so
every job received the repository's default token scopes. None of their
jobs writes back to GitHub: push.yml builds, tests and uploads
artifacts, changelog.yml posts to Discord with its own token, and
discord.yml only calls a webhook. push.yml and changelog.yml get a
read-only token, discord.yml gets none at all, which also shrinks what
a pull_request_target run can reach.
actions/checkout writes the job token into .git/config by default, so
every later step, including third-party actions and the packages they
install, can read it. None of the 13 checkouts in push.yml,
changelog.yml and copilot-setup-steps.yml pushes with git, so they no
longer keep the token. The claude.yml and pullfrog.yml checkouts are
untouched: those agents commit back and their token path is theirs to
decide.
@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
bugs Ready Ready Preview Oct 19, 2026 4:24pm UTC
remotion Ready Ready Preview Oct 19, 2026 4:24pm UTC

Request Review

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

ℹ️ Minor suggestions only. All the pins check out — one consistency nit inline, plus the merge-time checks below.

Reviewed changes

Reviewed the 5 hand-written workflows this PR touches (pullfrog.yml intentionally left as its header requests).

  • Third-party actions pinned to commit SHAs — oven-sh/setup-bun, rharkor/caching-for-turbo, anthropics/claude-code-action, ruby/setup-ruby and shivammathur/setup-php now reference full-length commit SHAs with the version kept as a trailing comment.
  • Workflow token scoping — push.yml and changelog.yml add permissions: contents: read; discord.yml adds permissions: {}.
  • Checkout credentials dropped — 13 actions/checkout steps gain persist-credentials: false; the two agent workflows that commit back are left untouched.

Every pinned SHA resolves to the upstream tag it claims — I checked v2.1.2, v2.3.11, v1.0.249, v1.329.0 and 2.40.0, and the two annotated tags dereference to exactly the pinned commits. None of the restricted workflows performs a git push, and none of the in-scope actions authenticates a GitHub API call with the token (IdanHo/action-discord reads the event payload off disk; discord-poster/post.ts fetches the public release unauthenticated), so the narrowed permissions and stripped credentials are safe here.

ℹ️ Merge-time operational checks

Two follow-ups ride on this change but live outside the diff.

Technical details
# Pinned-action operational follow-ups

## Affected sites
- `.github/workflows/*.yml` — 25 third-party refs now frozen to SHAs
- `.github/workflows/discord.yml`, `push.yml`, `changelog.yml` — new `permissions` blocks

## Required outcome
- Confirm the repo's **allowed-actions** policy before merge. If it restricts third-party actions by tag pattern (`owner/action@vX`), the new SHA refs will not match and every job using them will be refused — switch patterns to `owner/action@*` first.
- Add dependency automation (e.g. a `.github/dependabot.yml` `github-actions` entry) so the frozen SHAs still receive upstream security patches; otherwise this trades a movable-tag risk for a stale-pin risk.

## Open questions for the human
- Is the allowed-actions policy currently tag-based (the PR body raises this)?
- Should `pullfrog.yml`'s `pullfrog/pullfrog@v0` (privileged: `id-token: write`, `contents: write`) also be pinned, via the upstream Pullfrog template?

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash | 𝕏

- uses: actions/checkout@main
- uses: oven-sh/setup-bun@v2.1.2
with:
persist-credentials: false

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.

Since this checkout step is being hardened anyway: it still tracks the floating @main branch, unlike the actions/checkout@v6 used in every other workflow. @main is the least reproducible ref and doesn't match the PR's own "first-party actions stay on their tags" rule — bump to @v6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JonnyBurger
JonnyBurger merged commit fb3825c into remotion-dev:main Oct 19, 2026
16 checks passed

This branch was successfully deployed

2 active deployments
Preview – remotion — 569e03fd Deployed Oct 19, 2026 by vercel[bot]
Preview – bugs — 569e03fd Deployed Oct 19, 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.

2 participants