Improved Renovate handling of CVE-driven dependency updates#28040
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThis PR updates the Renovate configuration to automate handling of security vulnerability alerts. It adds a 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- security PRs were stranded for weeks behind the weekend schedule and the dashboard-approval gate, then went stale from merge conflicts - adds a vulnerabilityAlerts override so CVE updates skip the weekend schedule and dashboard gate and stay rebased against main; the 72h release-age soak is kept so a malicious "fix" publish can't fast-track - adds a packageRule to automerge non-major security updates after CI; security majors still wait for human review
50ab52e to
c3c6554
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/renovate.json5:
- Around line 58-69: The Renovate config is incorrectly targeting vulnerability
alerts: keep the top-level "vulnerabilityAlerts" block but remove reliance on
"minimumReleaseAge" for security PR throttling and stop using the unsupported
"isVulnerabilityAlert" inside "packageRules"; instead move any rules that should
apply to vulnerability/security alerts into an "alertPackageRules" array and
explicitly match the update types you want (e.g., "matchUpdateTypes":
["patch","minor","digest"]) or other supported matchers, and ensure
automerge/approval settings that would fast-track alerts are not applied in
normal "packageRules" but are handled via "alertPackageRules" so security alerts
are not auto-merged before the intended delay.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c938e3d2-2d6b-40e5-9d12-395ffe4c52ff
📒 Files selected for processing (1)
.github/renovate.json5
| // CVE-driven updates skip the weekend schedule and the dashboard- | ||
| // approval gate, and stay rebased against main so conflicts don't | ||
| // strand them. The 72h release-age soak is deliberately kept so a | ||
| // malicious "fix" publish can't fast-track into main. Automerge is | ||
| // configured per update-type in packageRules below so security | ||
| // majors still wait for human review. | ||
| "vulnerabilityAlerts": { | ||
| "schedule": ["at any time"], | ||
| "rebaseWhen": "behind-base-branch", | ||
| "minimumReleaseAge": "3 days", | ||
| "dependencyDashboardApproval": false, | ||
| "labels": ["dependencies", "security"] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and print relevant parts of the file with line numbers
file=".github/renovate.json5"
if [ ! -f "$file" ]; then
echo "Missing $file"
exit 1
fi
echo "== File: $file (line count) =="
wc -l "$file"
echo
echo "== Lines 45-90 =="
nl -ba "$file" | sed -n '45,95p'
echo
echo "== Lines 220-300 =="
nl -ba "$file" | sed -n '220,310p'
echo
echo "== Search for vulnerabilityAlerts / packageRules occurrences =="
rg -n "vulnerabilityAlerts|isVulnerabilityAlert|packageRules" "$file"Repository: TryGhost/Ghost
Length of output: 214
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and print relevant parts of the file with line numbers
file=".github/renovate.json5"
if [ ! -f "$file" ]; then
echo "Missing $file"
exit 1
fi
echo "== File: $file (line count) =="
wc -l "$file"
echo
echo "== Lines 45-90 =="
nl -ba "$file" | sed -n '45,95p'
echo
echo "== Lines 220-300 =="
nl -ba "$file" | sed -n '220,310p'
echo
echo "== Search for vulnerabilityAlerts / packageRules occurrences =="
rg -n "vulnerabilityAlerts|isVulnerabilityAlert|packageRules" "$file"Repository: TryGhost/Ghost
Length of output: 214
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".github/renovate.json5"
[ -f "$file" ] || { echo "Missing $file"; exit 1; }
echo "== File: $file (line count) =="
wc -l "$file"
echo
echo "== Lines 45-95 =="
awk 'NR>=45 && NR<=95 {printf "%5d\t%s\n", NR, $0}' "$file"
echo
echo "== Lines 220-295 =="
awk 'NR>=220 && NR<=295 {printf "%5d\t%s\n", NR, $0}' "$file"
echo
echo "== Search for vulnerabilityAlerts / isVulnerabilityAlert / packageRules occurrences =="
rg -n "vulnerabilityAlerts|isVulnerabilityAlert|packageRules" "$file"Repository: TryGhost/Ghost
Length of output: 6155
🌐 Web query:
Renovate vulnerabilityAlerts minimumReleaseAge semantics vulnerability alerts PRs skip minimumReleaseAge
💡 Result:
In Renovate, security-related updates automatically bypass the minimumReleaseAge check, allowing them to be raised as pull requests (PRs) as soon as they are detected [1][2]. Because these updates are prioritized for remediating known vulnerabilities, they do not wait for the release age threshold to pass [2]. Regarding the semantics of minimumReleaseAge, it is important to understand that Renovate does not wait for a package to stop receiving new releases; rather, it applies the waiting period to each specific version independently [1][2]. If multiple versions are released in quick succession, Renovate will evaluate each one against the threshold [1][2]. By default (as of Renovate 42), the internalChecksFilter is set to strict, meaning Renovate will not create branches or PRs for any updates that have not yet met the minimum release age requirements [2]. While security updates generally bypass this age check, there are known edge cases and complexities: 1. Vulnerability Detection: While dedicated security PRs (often triggered by platforms like GitHub or OSV) bypass the age threshold, this behavior applies specifically to updates that remediate known vulnerabilities [3][2]. 2. Limitations: The bypass mechanism does not always automatically extend to more complex scenarios, such as when an update that fixes a vulnerability is itself pending due to a newer, non-vulnerability-fixing version of the same package, or when using experimental features like osvVulnerabilityAlerts [3][4]. 3. Configuration: Because of these nuances, it is recommended to set internalChecksFilter to strict to ensure consistent application of the age gate, while relying on Renovate's built-in security detection to handle the bypasses for genuine vulnerability fixes [1][2].
Citations:
- 1: https://github.com/renovatebot/renovate/blob/main/docs/usage/key-concepts/minimum-release-age.md
- 2: https://docs.renovatebot.com/key-concepts/minimum-release-age/
- 3: osvVulnerabilityAlerts does not bypass minimumReleaseAge for pending versions renovatebot/renovate#42720
- 4: Give your feedback about the `osvVulnerabilityAlerts` experimental feature renovatebot/renovate#20542
🌐 Web query:
Renovate packageRules isVulnerabilityAlert matcher key
💡 Result:
In Renovate, there is no configuration key named isVulnerabilityAlert within packageRules [1][2]. To apply rules specifically to vulnerability alert PRs, you should use the alertPackageRules configuration option instead [3]. The alertPackageRules option is designed to handle dependency updates that originate from vulnerability alerts (such as those from GitHub Dependabot alerts or OSV) [3]. It accepts the same configuration structure as packageRules, allowing you to use standard matchers like matchPackageNames, matchDatasources, matchFileNames, and matchCurrentVersion to conditionally apply settings (e.g., specific PR body notes, assignees, or labels) to security-related pull requests [3]. If you were looking for a way to detect if a pull request is a vulnerability alert within a general packageRules block, Renovate does not provide a direct matcher for this status. Use alertPackageRules to define behavior specifically for these security updates [3].
Citations:
- 1: https://docs.renovatebot.com/configuration-options/
- 2: https://github.com/renovatebot/renovate/blob/main/docs/usage/configuration-options.md
- 3: Renovate doesn't open PR's for certain vulnerabilityAlerts (Case sensitive packages?) renovatebot/renovate#29230
Fix Renovate config: vulnerability alert security PRs bypass minimumReleaseAge, and packageRules[].isVulnerabilityAlert isn’t a valid matcher.
.github/renovate.json5lines 64-69:minimumReleaseAge: "3 days"won’t enforce a 72h cooldown for vulnerability-alert/security updates (Renovate bypasses it)..github/renovate.json5lines 243-258:isVulnerabilityAlertisn’t supported inpackageRules; if ignored, this rule will automerge all patch/minor/digest updates. UsealertPackageRules(or propermatch...keys) to target vulnerability alerts specifically.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/renovate.json5 around lines 58 - 69, The Renovate config is
incorrectly targeting vulnerability alerts: keep the top-level
"vulnerabilityAlerts" block but remove reliance on "minimumReleaseAge" for
security PR throttling and stop using the unsupported "isVulnerabilityAlert"
inside "packageRules"; instead move any rules that should apply to
vulnerability/security alerts into an "alertPackageRules" array and explicitly
match the update types you want (e.g., "matchUpdateTypes":
["patch","minor","digest"]) or other supported matchers, and ensure
automerge/approval settings that would fast-track alerts are not applied in
normal "packageRules" but are handled via "alertPackageRules" so security alerts
are not auto-merged before the intended delay.
Summary
CVE-driven dependency updates have been getting stranded for weeks. Renovate's weekend-only schedule and the dashboard-approval gate for major bumps apply equally to security PRs, so a green-CI security patch can sit until merge conflicts pile up. Examples: #27595 (postcss, two medium CVEs) stayed open 23+ days; #25456 (js-yaml security) merged after 141 days.
What this changes
.github/renovate.json5:vulnerabilityAlertsblock. Security PRs skip the weekend schedule and the dashboard-approval gate, and are rebased on every Renovate run so conflicts don't strand them.What this deliberately does not change
vulnerabilityAlertsblock keepsminimumReleaseAge: "3 days", matchingsecurity:minimumReleaseAgeNpmfrom the shared preset. This is the window for malware scanners to catch a compromised publish, and "it's a security fix, merge it fast" is exactly the framing a supply-chain attacker uses. The soak gates automerge only, so a genuinely-exploited 0-day can still be merged by hand sooner.Test plan
renovate.json5is parsed by Renovate, not Ghost CI — success here is JSON5 validity)