Skip to content

SRE-901: Install Renovate from the lockfile - #93

Merged
CiaranMn merged 3 commits into
mainfrom
t/sre-901-harden-the-centralized-renovate-workflow-against-compromised
Aug 4, 2026
Merged

SRE-901: Install Renovate from the lockfile#93
CiaranMn merged 3 commits into
mainfrom
t/sre-901-harden-the-centralized-renovate-workflow-against-compromised

Conversation

@TimDiekmann

@TimDiekmann TimDiekmann commented Aug 4, 2026

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

Install Renovate from the lockfile this repo already ships, instead of a bare npm install --global renovate@<version> that resolves fresh at run time.

🔗 Related links

🚫 Blocked by

None.

🔍 What does this change?

housekeeping-dependencies.yml:

  • npm install --global "renovate@$VERSION"npm ci --ignore-scripts --no-audit --no-fund against the committed package-lock.json. npm ci resolves nothing at run time
  • package-lock.json added to the checkout's sparse-checkout, which is why the lockfile was previously invisible to the workflow
  • the version lookup and RENOVATE_VERSION are deleted — with no renovate@<spec> string left, a package.json value cannot redirect the install
  • node_modules/.bin goes on $GITHUB_PATH, so Run Renovate keeps its bare run: renovate
  • the App token is scoped with owner + repositories to the calling repo, resolved from $GITHUB_REPOSITORY
  • contents: writeread. Renovate commits through the API with the App token
  • RENOVATE_ALLOW_SCRIPTS and RENOVATE_IGNORE_SCRIPTS set explicitly, restating Renovate's defaults

lint.yml: the Validate renovate config step had the same bare global install and now uses npm ci --ignore-scripts.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

  • --ignore-scripts skips the optional re2 native build. Renovate falls back to native RegExp and logs it; it was already being skipped in practice. Reversible with an explicit npm rebuild re2.
  • Cross-repo preset resolution is not verified by this PR's CI, because here the calling repo is the preset repo. Worth one manual workflow_dispatch in a consumer repo after merge.
  • The remaining scope is tracked in Linear.

🐾 Next steps

  • Tracked in SRE-901 and SRE-904.

🛡 What tests cover this?

  • lint.yml runs on this PR and exercises its own changed step.
  • housekeeping-dependencies.yml is in its own pull_request trigger's paths, and a PR run forces RENOVATE_DRY_RUN=extract, so the install and startup are exercised without any write.
  • Verified locally: the lockfile is committed, lockfileVersion: 3, and agrees with package.json, so npm ci will not fail its consistency check.

❓ How to test this?

  1. The Lint run on this PR covers the lint.yml change
  2. The Update dependencies run on this PR (dry-run extract) covers the install
  3. After merge, trigger Housekeeping manually in a consumer repo

📹 Demo

Not applicable, CI-only change.

… actions

Install Renovate locally with --ignore-scripts instead of globally, scope the App token to the calling repo, and drop contents: write.
@TimDiekmann TimDiekmann self-assigned this Aug 4, 2026
@TimDiekmann
TimDiekmann marked this pull request as ready for review August 4, 2026 13:33
@TimDiekmann
TimDiekmann requested review from CiaranMn and a lite review from Copilot August 4, 2026 13:33
@cursor

cursor Bot commented Aug 4, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes CI supply-chain and GitHub Actions permissions for dependency automation; mis-scoped App tokens or lockfile drift could break Renovate runs or preset resolution in consumer repos until validated post-merge.

Overview
Hardens centralized Renovate automation after a compromised transitive dependency could enter CI through runtime npm install --global renovate@<version> resolution.

housekeeping-dependencies.yml now sparse-checkouts package-lock.json, runs npm ci --ignore-scripts (no version jq step), and puts node_modules/.bin on PATH so renovate still runs unchanged. Workflow contents drops to read (commits use the App token), the App token is scoped to the calling repo via owner + repositories, and RENOVATE_ALLOW_SCRIPTS / RENOVATE_IGNORE_SCRIPTS are set explicitly.

lint.yml uses the same lockfile install for renovate-config-validator instead of a global Renovate install.

Reviewed by Cursor Bugbot for commit db91559. Bugbot is set up for automated code reviews on this repo. Configure here.

CiaranMn
CiaranMn previously approved these changes Aug 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the centralized Renovate reusable workflow to reduce blast radius if a compromised dependency or action enters CI, by tightening permissions, narrowing GitHub App token scope, and disabling install-time scripts.

Changes:

  • Drops workflow permissions.contents from write to read.
  • Scopes the GitHub App token to the calling repository using owner + repositories derived from $GITHUB_REPOSITORY.
  • Installs Renovate into $RUNNER_TEMP with npm install --ignore-scripts and runs it via an explicit binary path; explicitly sets RENOVATE_ALLOW_SCRIPTS=false and RENOVATE_IGNORE_SCRIPTS=true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@TimDiekmann
TimDiekmann enabled auto-merge August 4, 2026 13:42
…untime

npm ci cannot pull a package published after the lockfile was written, which is what let the malicious cacheable-request into the tree. This also removes the renovate@<spec> string, so a package.json value can no longer redirect the install.
Copilot AI review requested due to automatic review settings August 4, 2026 13:58
@TimDiekmann TimDiekmann changed the title SRE-901: Harden the centralized Renovate workflow against compromised actions SRE-901: Install Renovate from the lockfile and drop the privilege it did not need Aug 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (3)

.github/workflows/housekeeping-dependencies.yml:175

  • Even after adding the install dir to PATH, invoking Renovate via the resolved binary path avoids any accidental PATH shadowing and matches the PR’s stated approach ("invoked through the resolved binary path").
        run: renovate

.github/workflows/housekeeping-dependencies.yml:6

  • The workflow now treats the Renovate version as coming from package-lock.json, but the pull_request.paths filter still only watches package.json. A PR that only updates package-lock.json (e.g., a Renovate bump) would not trigger this workflow’s PR dry-run, reducing coverage for the new install path.
# The Renovate version is locked in /package-lock.json and managed by Renovate itself.
#
# Uses OIDC token to resolve the correct checkout ref for the lockfile.

.github/workflows/housekeeping-dependencies.yml:143

  • PR description says Renovate is installed under $RUNNER_TEMP/renovate, but the workflow currently installs into the workspace ($PWD/node_modules). Installing into $RUNNER_TEMP better matches the stated hardening goal and avoids mixing the tool install with the checked-out repo content.
      - name: Install Renovate
        run: |
          npm ci --ignore-scripts --no-audit --no-fund
          echo "$PWD/node_modules/.bin" >> "$GITHUB_PATH"

@TimDiekmann TimDiekmann changed the title SRE-901: Install Renovate from the lockfile and drop the privilege it did not need SRE-901: Install Renovate from the lockfile Aug 4, 2026
@CiaranMn
CiaranMn disabled auto-merge August 4, 2026 15:25
@CiaranMn
CiaranMn added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit 9957be5 Aug 4, 2026
7 checks passed
@CiaranMn
CiaranMn deleted the t/sre-901-harden-the-centralized-renovate-workflow-against-compromised branch August 4, 2026 15:32
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