The Dependency Review API in GitHub: Seeing Risk Before You Merge It

The Dependency Review API in GitHub: Seeing Risk Before You Merge It

A complete, beginner-friendly guide to how GitHub's Dependency Review API compares the open-source packages your project depends on, before a pull request is ever merged — what it returns, how it works internally, and how to use it well.

Picture a chef who insists on inspecting every ingredient delivery before it enters the kitchen — checking what’s new in the crate, whether anything has an expired safety certificate, and whether the supplier’s terms have quietly changed. Modern software is built the same way, out of thousands of small “ingredients” called dependencies, pulled in from open-source package registries. The Dependency Review API is GitHub’s version of that inspection: a way to look at exactly what dependencies a pull request would add, remove, or change, and whether any of them carry known security problems, before those changes ever enter the codebase.

1What Exactly Is the Dependency Review API?

Starting with the plain-language idea before touching any technical detail.

Almost every modern application depends on external packages — libraries someone else wrote, published to a registry like npm, PyPI, RubyGems, or Maven, and pulled into a project through a manifest file such as package.json or requirements.txt. Over the life of a project, those dependencies get added, upgraded, downgraded, and removed constantly, often inside pull requests that also contain unrelated application code.

The Dependency Review API is a GitHub REST API endpoint that compares the full set of dependencies between two points in a repository’s history — typically the base branch and the head of a pull request — and returns a structured “diff” of exactly what changed, along with any known security vulnerabilities and license information for those dependencies.

Simple Analogy

Think of it as the “Track Changes” feature in a word processor, but for your project’s ingredient list instead of your prose. Instead of showing which sentences were added or deleted, it shows which packages were added, removed, or bumped to a new version — and flags any of them that are known to be unsafe.

It is closely related to, but distinct from, the dependency review feature you might already see as a visual diff on the “Files changed” tab of a pull request in the GitHub web interface. The visual feature is what a human sees; the API is the underlying data source that powers it — and that other tools, scripts, and automated checks can call directly.

Term

Dependency Graph

GitHub’s continuously updated map of every dependency a repository uses, built by parsing manifest and lock files.

Term

Manifest / Lock File

Files like package.json or package-lock.json that declare which package versions a project uses, directly or indirectly.

Term

BASEHEAD

The API’s way of describing a comparison range — a base commit or branch and a head commit or branch, written as base...head.

Term

Advisory

A published security notice describing a known vulnerability in a specific package and version range, sourced from the GitHub Advisory Database.

2Why This Feature Exists

The supply-chain security problem this API is built to address.

A typical application might declare a few dozen direct dependencies in its manifest, but pull in hundreds more indirectly — dependencies of dependencies, several layers deep. Very few developers manually audit that entire tree on every pull request; it simply isn’t practical by hand. Attackers have learned to exploit exactly this gap, publishing malicious versions of popular packages, or waiting for known vulnerabilities in older versions to be reused by projects that never got around to upgrading.

!
Common Misconception

People sometimes assume vulnerability scanning only matters for a project’s own code. In practice, the overwhelming majority of the code running inside a typical application was written by someone else, as a dependency — which is exactly where this feature focuses its attention.

The Dependency Review API turns an invisible, easy-to-skip step — “did this pull request just add something risky?” — into a structured, machine-readable answer that can be checked automatically, every single time, without relying on a human reviewer noticing a one-line change buried in a long lock file diff.

Every PR
comparison can run automatically
Vulnerabilities + Licenses
two kinds of risk surfaced together
Direct & Indirect
dependencies deep in the tree are covered

3Where It Fits Among GitHub’s Supply-Chain Features

The Dependency Review API doesn’t work alone — it sits on top of, and alongside, several related pieces.

GitHub’s supply-chain security tooling is built in layers, and understanding the layering prevents a lot of confusion about which piece does what.

Dependency Graph

The foundation. GitHub parses manifest and lock files in a repository to build a continuously updated graph of every dependency it uses, direct and indirect. Every other feature described here reads from this graph.

Dependency Review API

Compares two points in that graph — usually a pull request’s base and head — and returns what changed, plus vulnerability and license data for the changed packages.

Dependency Review Action

A ready-made GitHub Actions workflow step that calls the API on GitHub’s behalf inside a pull request, and can be configured to fail the check if it finds dependencies above a chosen severity threshold.

Dependency Submission API

A separate, related API that lets build tools submit dependency information directly — useful for ecosystems where GitHub can’t fully determine the dependency tree just by reading manifest files (for example, some compiled languages).

flowchart TD
    A[Manifest & Lock Files in Repo] --> B[Dependency Graph]
    S[Dependency Submission API] --> B
    B --> C[Dependency Review API]
    C --> D[Dependency Review Action]
    C --> E[Files Changed Tab in PR UI]
    D --> F{Severity Above Threshold?}
    F -- Yes --> G[PR Check Fails]
    F -- No --> H[PR Check Passes]
        
FIG 1 — The dependency graph feeds the Dependency Review API, which in turn powers both the automated action and the visual pull request diff.
“The API doesn’t guess what changed — it reads the same dependency graph GitHub already maintains, and simply asks: what’s different between these two points?”

4The Anatomy of a Request and Response

What you actually ask for, and what comes back, described conceptually.

A request to the Dependency Review API is aimed at a specific repository and asks it to compare two references — a base and a head, written together as a single comparison range. Those references can be branch names, tags, or commit identifiers; the API works out the dependency state at each point and produces the difference between them.

Field in the ResponseWhat It Tells You
Change typeWhether a dependency was added, removed, or had its version changed.
Package ecosystemWhich package registry the dependency comes from — npm, PyPI, Maven, RubyGems, and others.
VersionThe specific version involved on each side of the comparison.
VulnerabilitiesAny known security advisories affecting that package and version, including a severity rating.
LicenseThe declared license of the package, useful for organizations with license-compliance policies.
ScopeWhether the dependency is used at runtime or only during development, where that information is available.
Simple Analogy

It’s similar to comparing two shopping receipts from the same grocery store, one from last week and one from today, and getting back a tidy list: “removed 2 items, added 3 items, one item’s brand changed” — except here, some items also come back tagged with a food-safety recall notice.

i
Tip

Because the response is structured data rather than a rendered page, it’s straightforward to feed into custom tooling — a Slack notification, a compliance dashboard, or a custom gate beyond what the ready-made action offers.

5Internal Working — What Happens When a Pull Request Opens

Tracing the sequence from an opened pull request to a finished check.

When a contributor opens a pull request that changes a manifest or lock file, a chain of events can be set in motion, most commonly through the dependency review action running as part of a GitHub Actions workflow.

sequenceDiagram
    participant C as Contributor
    participant P as Pull Request
    participant W as Actions Workflow
    participant D as Dependency Review API
    participant G as Dependency Graph

    C->>P: Open PR changing package.json
    P->>W: Triggers dependency review workflow
    W->>D: Request comparison (base...head)
    D->>G: Read dependency state at base
    D->>G: Read dependency state at head
    G-->>D: Dependency lists for both points
    D->>D: Compute diff + attach vulnerability/license data
    D-->>W: Structured comparison result
    W->>W: Apply configured thresholds (severity, licenses)
    alt Above threshold or disallowed license found
        W-->>P: Check fails, details shown in PR
    else Nothing concerning found
        W-->>P: Check passes
    end
        
FIG 2 — The workflow calls the API once per comparison and then applies its own pass/fail rules to the structured result.

Notice that the API itself doesn’t decide pass or fail — it only reports facts: what changed, and what’s known about it. The decision of what counts as “too risky” (which severity level, which licenses are disallowed) is configured separately, in the action or in whatever tool is calling the API. This separation keeps the underlying data reusable for many different policies.

!
Common Mistake

Assuming the API “blocks” risky pull requests by itself. It only reports data — enforcement (failing a check, requiring changes) is a separate configuration step layered on top, most commonly via the dependency review action’s severity threshold.

6Data Flow and Lifecycle Across a Project’s Life

Zooming out from a single request to how this data stays current over time.

1

Dependency Graph Built and Kept Current

As manifest and lock files change on any branch, GitHub keeps its internal dependency graph up to date automatically, so comparisons always reflect the latest known state.

2

Pull Request Opened or Updated

Any push to a pull request branch that touches dependency files becomes a new potential comparison point between base and head.

3

Comparison Requested

The dependency review action, or a custom script with API access, requests a diff for that specific base-and-head range.

4

Vulnerability and License Data Attached

Each changed dependency is cross-referenced against the GitHub Advisory Database and its declared license, and that information is attached to the response.

5

Policy Applied and Result Surfaced

Whatever called the API decides what to do with the result — fail a check, post a comment, show a visual diff — and that outcome is what the reviewer or contributor actually sees.

One subtlety worth understanding: because advisories are published continuously, a dependency that looked clean when a pull request was first opened can later be flagged if a new vulnerability is disclosed for it. Re-running the check, rather than relying on a result from days earlier, keeps the information current.

7Where This Feature Is Available

Availability differs between public and private repositories, which trips up teams moving code between the two.

Repository TypeAvailability
Public repositoriesAvailable on all plans, and cannot be turned off.
Private repositoriesAvailable to organizations on GitHub Enterprise Cloud with a license for GitHub Advanced Security.
i
Tip

A pull request that behaves perfectly in a public sample repository during evaluation may not show the same checks once real work moves into a private, organization-owned repository — because the licensing requirement kicks in there. Confirm Advanced Security licensing before relying on this for private work.

This split is intentional: GitHub treats supply-chain visibility for open-source, publicly visible code as a broadly available safety feature, while treating it as part of the more advanced, licensed security suite once private, proprietary code is involved.

8The Dependency Review Action vs. Calling the API Directly

Two different ways to consume the same underlying data, suited to different needs.

Dependency Review Action

  • Pre-built, maintained GitHub Actions workflow step — nothing to write from scratch.
  • Configurable options like a minimum severity to fail on, and lists of allowed or disallowed licenses.
  • Designed specifically for the “fail a pull request check” use case.

Calling the API Directly

  • Full flexibility to build custom logic — dashboards, notifications, or policies the action doesn’t natively support.
  • Useful outside the pull request context too, such as auditing an arbitrary commit range on demand.
  • Requires handling authentication, request construction, and response parsing yourself.

Most teams start with the ready-made action, since it covers the most common need — failing a pull request when a newly introduced dependency is too risky — without writing any integration code. Teams with more specific requirements, such as routing results into an existing compliance system, tend to graduate to calling the API directly, often from within their own Actions workflow.

9A Subtle Pitfall: Race Conditions with the Dependency Submission API

A detail that matters specifically for ecosystems that rely on the separate Dependency Submission API.

Some ecosystems can’t be fully understood just by reading a manifest file — a compiled language’s actual dependency tree might only be knowable after a build step runs. For these cases, GitHub offers the Dependency Submission API, letting build tooling submit the resolved dependency list directly, which then feeds into the same dependency graph the review API reads from.

!
Common Mistake

Running the dependency submission step and the dependency review action in separate, uncoordinated workflows can create a timing problem: if the review runs before submission has finished updating the graph, it may compare against stale or incomplete dependency data, silently missing something it should have caught.

The safer pattern is to keep both steps inside the same GitHub Actions workflow, in a defined order, so the review action always runs after the submission step has finished — giving up direct control over exact timing in exchange for a guarantee that the comparison sees complete, current data.

10Advantages, Disadvantages, and Trade-offs

Weighing what this feature genuinely improves against its real limitations.

Advantages

  • Surfaces dependency risk automatically, on every relevant pull request, without relying on a reviewer noticing a lock file change.
  • Covers indirect dependencies buried deep in the tree, not just the packages a developer explicitly typed into a manifest.
  • Combines two distinct risk signals — known vulnerabilities and license terms — in one comparison.
  • Structured, machine-readable output that’s easy to integrate into custom tooling beyond the default action.
  • Always available on public repositories at no extra cost, lowering the barrier for open-source projects.

Disadvantages / Trade-offs

  • Private-repository usage requires GitHub Enterprise Cloud plus a GitHub Advanced Security license, which not every organization has.
  • Only as good as the underlying advisory data — brand-new, undisclosed vulnerabilities won’t be flagged until they’re published.
  • Some ecosystems need the separate Dependency Submission API for full accuracy, adding setup complexity.
  • Enforcement is a configuration choice layered on top, not automatic — a misconfigured or missing threshold means risky changes can still slip through.
  • Uncoordinated workflows can introduce the race-condition pitfall described in Chapter 9.

11Security Considerations

How this feature fits into a broader supply-chain security strategy, and what it doesn’t cover.

Dependency review is one part of a larger picture that typically also includes secret scanning, code scanning, and Dependabot alerts and updates. Together, these cover different stages: dependency review catches risky changes at the pull request stage, before merge; Dependabot alerts continue watching already-merged dependencies for newly disclosed vulnerabilities over time; code scanning looks at the project’s own source code rather than its dependencies.

Protects Against

Introducing a Known-Vulnerable Package

Catches a pull request that adds or upgrades to a version with a published advisory.

Protects Against

Unnoticed License Changes

Flags dependencies whose license terms may conflict with an organization’s policy.

Does Not Protect Against

Zero-Day, Undisclosed Vulnerabilities

If no advisory exists yet for a flaw, the API has nothing to report — it reflects known, published data.

Does Not Protect Against

Vulnerabilities in Already-Merged Code

This feature focuses on pull request comparisons; ongoing monitoring of what’s already merged is Dependabot’s role.

12Monitoring, Logging, and Keeping Results Visible

Making sure the signal this feature produces actually gets seen and acted on.

Results from the dependency review action appear directly on the pull request as a check, along with a detailed breakdown on the “Files changed” tab, making them visible in the same place a reviewer already looks. Teams calling the API directly are responsible for deciding how results surface — a common pattern is posting a summary comment on the pull request, or sending a notification to a security channel when severity crosses a defined threshold.

i
Tip

Treat a dependency review check that’s frequently overridden or bypassed as a signal worth investigating — it may mean the severity threshold is miscalibrated for the project, generating noise the team has learned to ignore.

Because advisory data changes over time, a periodic, project-wide review of currently allowed licenses and severity thresholds — not just per-pull-request checks — helps catch policy drift as an organization’s risk tolerance or compliance requirements evolve.

13Design Patterns and Anti-patterns

Approaches that work well in practice, and traps worth avoiding.

PATTERN-01 Recommended
Pattern

Graduated Severity Gating: start with a lenient severity threshold (fail only on “critical”) and tighten it over time as the team clears out existing risky dependencies.

Why It Works

A very strict threshold applied on day one to an existing project can produce an overwhelming wall of failing checks, discouraging teams from using the feature at all. Starting lenient and tightening builds trust in the signal.

ANTI-PATTERN-01 Avoid
Problem

Running dependency submission and dependency review as separate, independently triggered workflows with no defined order.

Why It’s Harmful

As covered in Chapter 9, this can create a race condition where the review runs against incomplete dependency data, silently reducing its accuracy.

Correct Approach

Keep submission and review steps in the same workflow, with submission always completing first.

ANTI-PATTERN-02 Avoid
Problem

Treating a passing dependency review check as proof that a pull request is completely safe.

Why It’s Harmful

As discussed in Chapter 11, the check only reflects currently published advisory data — it says nothing about undisclosed vulnerabilities or issues outside dependency changes entirely.

Correct Approach

Treat it as one layer among several — code review, code scanning, and ongoing monitoring — rather than a complete safety guarantee on its own.

14Best Practices and Common Mistakes

A condensed checklist drawn from everything discussed so far.

Best Practice

Order Workflow Steps Deliberately

Run dependency submission before dependency review, in the same workflow, whenever both are used.

Best Practice

Define an Explicit License Policy

Configure allowed and disallowed licenses rather than relying only on severity thresholds.

Best Practice

Start Lenient, Tighten Gradually

Especially on existing projects with pre-existing dependency debt.

Best Practice

Confirm Licensing for Private Repos

Verify GitHub Advanced Security licensing before assuming this feature is active on private work.

Mistake

Ignoring Failing Checks Repeatedly

A team that habitually bypasses the check without investigating trains itself to ignore real findings too.

Mistake

Assuming It Covers Everything

Forgetting that it’s a pull-request-time check, not an ongoing monitor of already-merged dependencies.

15Real-World and Industry Examples

Concrete situations where these ideas show up in everyday engineering work.

Open-Source Maintainer Guarding Contributions

A popular open-source library adds the dependency review action to its public repository at no extra cost, automatically catching a well-meaning contributor’s pull request that accidentally introduces an outdated, vulnerable version of a testing library.

Enterprise Enforcing a License Policy

A company with strict legal requirements around open-source licensing configures the action’s allowed-licenses list, catching a dependency change that would have introduced a copyleft-licensed package into proprietary, closed-source code.

Platform Team Building a Custom Dashboard

An internal platform team calls the API directly from a scheduled workflow across dozens of repositories, aggregating results into a single compliance dashboard that the default action alone wouldn’t provide.

Compiled-Language Project Using Dependency Submission

A team working in a compiled ecosystem where dependencies can’t be fully determined from a manifest alone integrates the Dependency Submission API into its build step, feeding accurate, resolved dependency data into the same graph the review API reads from.

16Frequently Asked Questions

Q1Does the Dependency Review API automatically block risky pull requests?

No, not by itself. It returns structured comparison data; deciding what counts as “too risky” and failing a check accordingly is handled separately, typically by the dependency review action’s configuration.

Q2Is this available for private repositories on a standard GitHub plan?

Private repository usage requires an organization on GitHub Enterprise Cloud with a GitHub Advanced Security license. It’s available on all public repositories regardless of plan.

Q3What’s the difference between the API and the visual diff on the “Files changed” tab?

The visual diff in the pull request UI is a human-facing presentation of dependency changes; the API is the underlying data source, callable directly for custom tooling and automation.

Q4Does it catch vulnerabilities that haven’t been publicly disclosed yet?

No. It relies on published advisory data. A vulnerability that hasn’t been disclosed or added to the advisory database yet won’t be flagged until it is.

Q5Do I need the Dependency Submission API to use dependency review?

Not always. Many ecosystems are fully understood just from manifest and lock files. Submission becomes important for ecosystems where the true dependency tree is only resolvable at build time.

Q6Can this feature check license compliance as well as security?

Yes. Alongside vulnerability data, results include license information, and the dependency review action supports configuring allowed and disallowed license lists.

Q7What comparison range does the API use for a typical pull request check?

It compares the base branch the pull request targets against the head of the pull request branch, reflecting exactly what that pull request would change if merged.

17Summary and Key Takeaways

The Dependency Review API gives GitHub a structured, automatable way to answer a question every pull request implicitly raises: what open-source packages would this change actually introduce, and is any of it known to be risky? By comparing a base and head reference against GitHub’s dependency graph and attaching vulnerability and license data to the result, it turns a step that’s easy to skip by hand into a consistent, repeatable check — whether consumed through the ready-made dependency review action or called directly for custom tooling.

Key Takeaways

  • It compares dependency states, not source code — a base-versus-head diff of what packages changed.
  • Covers direct and indirect dependencies — including packages buried deep in a lock file, not just top-level entries.
  • Reports vulnerabilities and licenses together — two distinct risk signals in one response.
  • The API reports; policy decides — enforcement thresholds are configured separately, most often via the dependency review action.
  • Availability differs by repository type — free and always-on for public repos, licensed via GitHub Advanced Security for private ones.
  • Order matters with dependency submission — run submission before review, in the same workflow, to avoid stale-data race conditions.
  • It reflects known, published advisories only — not a guarantee against undisclosed vulnerabilities.
  • Best used alongside other layers — code scanning, secret scanning, and Dependabot alerts for ongoing, post-merge monitoring.