Safeguard
Software Supply Chain Security

GitHub dependency graph and dependency review explained

How GitHub Dependency Graph and Dependency Review actually work, what GitHub Advanced Security adds on top, and where the coverage gaps are for teams relying on manifest-only scanning.

James
Principal Security Architect
7 min read

GitHub Dependency Graph has been quietly running in the background of every public repository since 2018, and as of 2024 it parses manifests and lockfiles across roughly 20 package ecosystems — npm, pip, Maven, Gradle, NuGet, RubyGems, Composer, Go modules, Cargo, and more. It's the data layer that powers Dependabot alerts, security advisories, and the dependency review checks that run on pull requests. For teams evaluating GitHub Advanced Security (GHAS), understanding exactly what Dependency Graph sees — and, just as importantly, what it doesn't see — is the difference between believing you have supply chain visibility and actually having it. This post breaks down how Dependency Graph and Dependency Review work, how GHAS builds on them, where the gaps are, and how Safeguard fills those gaps for teams that need software supply chain security beyond a single platform's manifest parser.

What Is GitHub Dependency Graph and How Does It Work?

GitHub Dependency Graph is a static analysis feature that scans manifest files (package.json, requirements.txt, pom.xml, go.mod, Gemfile, etc.) and, where available, their corresponding lockfiles to build a map of every direct and transitive dependency in a repository. It has been enabled by default on public repositories since October 2018, and repository admins can turn it on for private repositories under their organization's settings. When a lockfile is present — package-lock.json, yarn.lock, poetry.lock, Gemfile.lock — GitHub resolves the full transitive tree, sometimes surfacing hundreds of indirect dependencies from a manifest that lists only a dozen direct ones. Without a lockfile, GitHub can only see declared version ranges, which means the actual resolved version at build time may differ from what the graph reports. This data feeds two downstream features: Dependabot security alerts, which flag known CVEs against the resolved dependency list, and the dependency graph API, which third-party tools (including Safeguard) can query for a repository's declared dependency inventory.

What Is Dependency Review and When Does It Run?

Dependency Review is a pull-request-time check that diffs the dependency graph between a PR's base branch and head branch, and it only runs in that PR context — not continuously against your default branch. GitHub shipped the standalone dependency-review-action in 2021 and later folded an equivalent check directly into pull request UI for GHAS customers. When a PR introduces a new dependency or bumps a version, the check compares the "before" and "after" dependency graphs and flags newly introduced vulnerabilities, license changes, and (for GHAS customers) OpenSSF Scorecard signals like maintenance activity or the presence of a security policy. Teams can configure the action to fail a check on a severity threshold (say, block on "high" or above) or on a denied license list (e.g., GPL-3.0). Because it's PR-scoped, a vulnerability introduced by merging directly to a protected branch without a PR, or one disclosed after merge for a dependency already in main, won't be caught by dependency review — that's Dependabot alerts' job, and it runs on a different cadence (typically a daily re-scan against the advisory database).

How Does GitHub Advanced Security Extend Dependency Graph?

GitHub Advanced Security extends the free dependency graph with enforcement, code scanning, and secret scanning bundled into one paid SKU that has historically been priced per active committer, around $49/month, before GitHub moved toward more granular, consumption-based packaging in 2024. On top of the free dependency graph and public-repo Dependabot alerts, GHAS adds: CodeQL code scanning for first-party code (not dependencies), push protection and secret scanning across the full commit history, and the ability to enforce dependency review as a required, blocking status check on private repositories. Without GHAS, private repositories get dependency graph data and Dependabot alerts, but PR-level blocking dependency review and org-wide security overview dashboards require the paid tier. This is the core commercial logic: the data collection (dependency graph) is free and open by default, while the enforcement and aggregation layer (GHAS) is the product GitHub sells against that data.

What Are the Limitations of GitHub's Dependency Graph?

GitHub Dependency Graph's biggest limitation is that it's a manifest parser, not a build-time or runtime scanner, so it can miss what actually ships. It reads what your package manager files declare — not what your CI pipeline actually resolves, not what ends up in a compiled binary, and not what's baked into a container image beyond the base image referenced in a FROM line. A few concrete gaps: dependencies pulled in via private registries or vendored/copy-pasted source code aren't tracked at all; monorepos with dozens of manifests can produce a graph that's technically complete but operationally noisy, with no built-in risk prioritization across hundreds of repos; and there's no reachability analysis — a critical CVE in a transitive dependency gets the same flag whether the vulnerable function is called in your code path or not, which is a major source of alert fatigue on large engineering orgs. GitHub's dependency graph also only covers ecosystems it has explicit parsers for; internal or less common package formats (some Go private module setups, custom C/C++ dependency management, certain Docker multi-stage build patterns) fall outside its coverage entirely.

How Does Dependency Review Compare to a Full SBOM?

Dependency Review gives you a diff between two graph states, while a full SBOM (Software Bill of Materials) gives you a complete, exportable inventory of every component in a build artifact at a point in time — and increasingly, customers and regulators want the latter, not just the former. GitHub does let you export a dependency graph as an SPDX-format SBOM via the API or UI, which is useful for point-in-time compliance snapshots (e.g., satisfying a customer questionnaire or an Executive Order 14028-adjacent requirement). But that export is still sourced from manifest data, not from the actual built artifact, so it inherits the same limitation described above: it reflects declared dependencies, not what's provably in the shipped binary or container. Organizations under frameworks like SOC 2, FedRAMP, or NTIA minimum-elements guidance often need SBOMs generated per build/release, tied to a specific artifact hash, and retained for audit — a workflow GitHub's native tooling supports as a manual export rather than an automated, artifact-linked pipeline.

How Does This Play Out at Scale for Multi-Repo Organizations?

At scale, the gap shows up as fragmentation: a 200-repo organization running GHAS gets 200 separate dependency graphs and PR checks, with no single view of cross-repo dependency risk, duplicate vulnerable packages, or which teams are ignoring dependency review failures. GitHub's security overview dashboard (a GHAS feature) aggregates some of this at the org level, but it's scoped to what dependency graph and Dependabot already know, and it doesn't correlate findings with deployment status, runtime exposure, or business criticality of the affected service. Security and platform teams end up building their own aggregation layer on top of the GitHub API just to answer basic questions like "which of our internet-facing services currently depend on a package with a critical CVE disclosed this week."

How Safeguard Helps

Safeguard is built to sit on top of exactly this gap — treating GitHub's dependency graph and Dependabot alerts as one input among several, rather than the source of truth. Where GitHub gives you a manifest-level view per repository, Safeguard aggregates dependency and vulnerability data across your entire codebase, ties it to actual build artifacts and deployment context, and prioritizes findings by real exploitability and reachability instead of raw CVSS score alone — directly addressing the alert-fatigue problem that flat dependency review checks create. Safeguard generates artifact-linked SBOMs automatically at build time (not as a manual export), satisfying SOC 2 and compliance audit requirements without a separate manual process per release. It also correlates dependency risk with your actual deployed surface area, so a critical vulnerability in an unreachable code path or a decommissioned service doesn't get the same urgency as one sitting in a service handling production traffic. For teams already using GHAS, Safeguard doesn't replace GitHub's dependency graph — it ingests it, cross-references it against build and runtime data, and gives security and engineering teams one consolidated view instead of 200 separate PR checks. If your organization is deciding between GHAS alone and a layered approach, the practical test is simple: ask whether your current tooling can tell you, in one query, every currently-deployed service exposed to a CVE disclosed this morning. If the answer requires stitching together multiple dashboards, that's the gap Safeguard is built to close.

Never miss an update

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