Dependabot is the default security-update mechanism for millions of GitHub repos, and for most teams it is the first (and sometimes only) line of defense against known vulnerabilities in open source dependencies. It is free, it opens PRs automatically, and it is enabled with a single click. But engineers frequently ask the same questions in post-incident reviews: why did Dependabot miss this CVE, why did it not group the five PRs on the same library, and why did a security update break a build that a regular version update would not have. This post is a behavioral deep dive aimed at platform engineers and AppSec leads who rely on Dependabot in production. It covers how security updates differ from version updates, semver handling, transitive dependency behavior, PR grouping, and the known limitations - with concrete examples against the September 2023 Dependabot behavior.
How do security updates differ from version updates?
They are two separate features with different triggers and scopes. Dependabot version updates are configured in .github/dependabot.yml with package-ecosystem, directory, and schedule. They open PRs on a cadence (daily/weekly/monthly) regardless of vulnerability status and bump to the latest non-yanked version within your allow rules. Security updates, by contrast, are triggered by a GitHub Advisory Database (GHSA) match against your lockfile and open a PR only for the vulnerable dependency, targeting the lowest version that resolves the advisory. Security updates do not require dependabot.yml at all - they are enabled per-repo or org-wide in Settings and run continuously. This is the single most-misunderstood aspect of Dependabot in practice.
How does Dependabot handle semver?
Security updates prefer the smallest fix; version updates prefer the latest. For a security update, Dependabot resolves the minimum semver range that includes the fix. If you are on lodash@4.17.20 and the advisory is fixed in 4.17.21, the PR bumps to 4.17.21, not 4.17.23. This is deliberate - the theory is that the smaller bump is less likely to break. Version updates, conversely, go to the newest version that does not violate your ignore rules in dependabot.yml. The practical consequence is that a repo relying solely on security updates can accumulate many minor-version-behind dependencies, which is fine for patching but does not help with dependency hygiene.
How well does it handle transitive dependencies?
Poorly, and this is the most common complaint. If express@4.17.1 transitively pulls in a vulnerable version of qs, Dependabot will usually not open a PR to bump express even if bumping to a newer express fixes qs. Its heuristic only works when there is a direct version of the vulnerable package in your lockfile that can be overridden via an npm overrides field, a Yarn resolutions block, or a Maven dependency management section. For ecosystems like Python where transitive resolution is implicit, Dependabot frequently opens a PR that fails CI because the patched transitive version conflicts with another direct dep. Practitioners often supplement with npm overrides or renovate for transitive fixes.
Does it group related PRs?
Only with the April 2023 grouping feature, and only for version updates. GitHub shipped groups for Dependabot version updates in April 2023, allowing you to bundle same-ecosystem PRs by pattern - for example, grouping all aws-sdk-* packages into one PR. Security updates are not yet supported by the grouping feature as of September 2023, meaning if three vulnerable packages all get advisories on the same day, you receive three PRs. This is a documented limitation and a known pain point for repos with many packages from the same vendor (aws-sdk-js v2 packages, for example, regularly generate 6-12 simultaneous PRs after a CVE).
What does it miss?
GHSA-only coverage, rate limits, and malicious-package detection. Dependabot's vulnerability feed is GHSA plus OSV, which trails the commercial feeds (Snyk, Mend, Sonatype OSS Index) by typically 1-3 days on newly disclosed npm and pip issues. It also does not perform malicious-package detection - a typosquatted npm package that GHSA has not yet flagged will not trigger a security update. Dependabot runs on GitHub-hosted runners with internal rate limits; monorepos with 50+ package ecosystems can see update jobs silently throttled. Finally, Dependabot will not alert on a yanked version, only on versions with advisories.
When should you add another tool?
When you need faster intel, transitive fixes, or policy. Teams that need sub-24-hour intel on npm or PyPI issues add a commercial SCA (Snyk, Mend, Sonatype). Teams with many transitive issues add Renovate, which has more aggressive transitive-resolution strategies. Teams with license compliance needs need something other than Dependabot, which does not scan licenses at all.
Who wins for what workload?
- Free, GitHub-native baseline - Dependabot alone is sufficient.
- Monorepos with many same-vendor packages - Add Renovate for grouping.
- Regulated industries with license and SBOM needs - Dependabot is inadequate; add commercial SCA.
- Python-heavy estates with deep transitive trees - Supplement with
pip-auditor Safety. - Need malicious-package detection - Add Snyk, Socket, or similar.
How Safeguard Helps
Safeguard complements Dependabot by filling its three biggest gaps: transitive reachability, malicious-package intelligence, and policy gates. Teams continue to use Dependabot for automatic PRs and let Safeguard ingest the resulting SBOMs to flag which Dependabot alerts actually reach production code paths, which transitive dependencies are exploitable without a direct fix, and which packages have been flagged as malicious across ecosystems. Policy gates enforce "no critical with known exploit at release" regardless of whether Dependabot has opened a PR. Griffin AI summarizes the Dependabot backlog into a prioritized remediation queue so engineering effort goes to the handful of PRs that actually matter.