Safeguard
Product

Dependabot alerts vs CodeQL analysis: what's the difference

Dependabot flags known vulnerabilities in dependencies; CodeQL finds flaws in your own code. Here's how the two differ inside GitHub Advanced Security.

Aman Khan
AppSec Engineer
8 min read

If your GitHub organization has GitHub Advanced Security (GHAS) enabled, you're probably seeing two very different streams of findings in your Security tab: Dependabot alerts and CodeQL results. Teams often bucket both under "vulnerability scanning" and triage them the same way — but they answer different questions. Dependabot tells you that a package you depend on has a known, publicly disclosed vulnerability. CodeQL tells you that a specific pattern of unsafe logic exists somewhere in the code your team actually wrote.

Conflating the two leads to predictable problems: teams either drown in Dependabot noise for dependencies that are never invoked, or they assume CodeQL is scanning their third-party packages when it isn't. This post breaks down what each tool actually does, where GitHub Advanced Security's model draws the line between them, and where a dedicated supply chain security platform like Safeguard fills the gap both leave open.

What does Dependabot alerts actually check?

Dependabot is a software composition analysis (SCA) tool. It works off two things: your dependency graph (the manifests and lockfiles GitHub parses — package-lock.json, requirements.txt, go.sum, and similar files across supported ecosystems) and the GitHub Advisory Database, which aggregates CVEs and GitHub-reviewed advisories. When a version range in your manifest matches a known-vulnerable range in that database, Dependabot raises an alert and, where a fix is available, can open an automated pull request bumping the dependency to a patched version.

Two things follow directly from that mechanism:

  • Dependabot only knows about vulnerabilities that have already been disclosed and cataloged. It cannot find a flaw that hasn't been reported yet, and it cannot tell you anything about code your organization wrote in-house.
  • Dependabot matches on version metadata, not on usage. It flags a vulnerable package the moment it's present in the lockfile, regardless of whether the vulnerable function is ever called by your application. This is the single biggest source of Dependabot alert fatigue — a large fraction of alerts point at code paths that are never reachable at runtime.

What does CodeQL analysis actually check?

CodeQL is a static application security testing (SAST) engine. Instead of pattern-matching text, it compiles your codebase into a relational database and lets you run semantic queries against it — tracing how data flows from a source (like a user-controlled HTTP parameter) to a sink (like a SQL query or a file path) across function and file boundaries. GitHub and the security research community maintain a large library of open-source CodeQL queries covering common weakness classes (SQL injection, path traversal, SSRF, insecure deserialization, and so on), and teams can write custom queries for organization-specific patterns.

The key distinction: CodeQL analyzes the source code your team writes and controls. It runs on your first-party repository as part of a CI job (typically a GitHub Actions workflow) and produces results scoped to that codebase. It does not, by design, perform deep semantic analysis of the internals of your third-party dependencies — those are typically pulled in as compiled packages or vendored source that isn't the primary analysis target of your CodeQL configuration, even though CodeQL can be pointed at additional codebases if you set that up yourself.

Dependabot vs CodeQL: are they solving the same problem?

No — and this is the part that gets lost in "which scanner is better" framing. They sit at different layers of the software supply chain:

DimensionDependabot alertsCodeQL analysis
CategorySCA (dependency vulnerability matching)SAST (semantic source code analysis)
Data sourceGitHub Advisory Database + dependency graphCompiled CodeQL query packs run against your source
What it findsKnown, disclosed CVEs/advisories in dependency versionsCustom and known unsafe code patterns and data flows in first-party code
Can it catch a zero-day in your own code?NoPotentially, if a matching query exists
Can it catch a zero-day in a dependency?No — needs a published advisory firstOnly if you explicitly run CodeQL against that dependency's source
Remediation outputAutomated version-bump pull requestsLine-level findings requiring manual code fixes

Both are real, useful capabilities, and GitHub bundles them together under GitHub Advanced Security precisely because they're complementary rather than redundant. The gap isn't that one tool is better — it's that running them side by side still leaves a question neither answers on its own: given everything Dependabot and CodeQL just flagged, which findings actually matter for this specific application?

Where does the Dependabot + CodeQL combination fall short for supply chain risk?

Two structural gaps show up consistently for teams relying on GHAS as their complete supply chain security answer:

1. Neither tool tells you if a vulnerable dependency function is reachable from your code. Dependabot alerts on version presence. CodeQL, unless deliberately configured to analyze dependency source alongside your own, is scoped to first-party code. That leaves the question of reachability — whether the vulnerable function in a flagged package is ever called, directly or transitively, by your application's actual call paths — unanswered by default. Reachability is what separates a CVE that's a real, exploitable risk from one that's inert dead weight in your dependency tree.

2. Neither tool produces a unified, artifact-level provenance record. Dependabot alerts and CodeQL results are both scoped to source repositories and CI runs. Neither is designed to answer "what went into this specific build artifact, and can we prove it wasn't tampered with between commit and deploy?" — a question that SBOM generation, build provenance attestation (e.g., SLSA-style), and artifact signing are built to answer, and which sits outside what SCA and SAST scanning cover by design.

These aren't criticisms of Dependabot or CodeQL doing their jobs badly — they're doing exactly what SCA and SAST tools are supposed to do. The gap is that "vulnerability scanning" and "supply chain security" aren't the same scope of problem, and treating GHAS's two scanners as a complete supply chain security program leaves reachability analysis and artifact provenance as open questions.

Does alert volume from Dependabot and CodeQL actually get triaged, or just accumulate?

This is less a tooling question than an operational one, but it's worth naming because it's the practical failure mode most teams hit. Dependabot alerts scale with the size of your dependency tree — a modern JavaScript or Python service can easily have several hundred to a few thousand transitive dependencies, and each one is a candidate for a future advisory. CodeQL findings scale with codebase size and the breadth of the query packs you enable. Without a layer that correlates the two — a CodeQL-flagged data flow that happens to run through a Dependabot-flagged dependency, for instance, or a dependency vulnerability confirmed reachable from an internet-facing entry point — both alert streams tend to grow faster than triage capacity, and prioritization defaults to whatever severity score the advisory database assigned, which is a property of the vulnerability in isolation, not of your specific deployment.

How Safeguard Helps

Safeguard is built to sit on top of exactly this gap: it treats Dependabot-style dependency alerts and CodeQL-style code findings as two inputs into a single supply chain risk picture, rather than two separate dashboards to triage independently.

Concretely, Safeguard's platform:

  • Generates and continuously tracks SBOMs for your repositories and build artifacts, giving you a queryable inventory of every dependency — direct and transitive — independent of any single ecosystem's manifest format.
  • Performs reachability analysis to determine whether a vulnerable function flagged by a known-CVE match is actually invoked by your application's code paths, so a disclosed advisory in an unused code path can be deprioritized relative to one that's exploitable in your specific build.
  • Correlates findings across the software supply chain — dependency vulnerabilities, build metadata, and artifact provenance — into a single risk view, instead of leaving your team to manually cross-reference an SCA alert list against a separate SAST findings list.
  • Tracks build provenance and artifact integrity, addressing the "what actually shipped, and can we verify it" question that sits outside the scope of dependency scanning and source code analysis alike.

If your organization already relies on Dependabot and CodeQL through GitHub Advanced Security, Safeguard isn't positioned as a rip-and-replace — it's the correlation and prioritization layer that turns two separate alert streams into a ranked, reachability-aware view of what to fix first, plus the provenance tracking that neither SCA nor SAST scanning was designed to provide.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.