Block Vulnerable Dependencies at Pull Request Time
Run GitHub dependency review on every pull request and fail when a new dependency brings a known vulnerability or a denied license.
Task
Catch a risky dependency during review instead of after it is merged and shipped in a release.
When to use this
A routine dependency bump adds a transitive package with a high-severity advisory; the build stays green because nothing scans the dependency diff.
Prerequisites
- Dependency graph enabled for the repository
- GitHub Actions triggered on pull_request
- A license allowlist agreed with legal
Steps
1. Add the dependency review action with severity and license policy.
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
deny-licenses: GPL-3.0, AGPL-3.0
Expected output: The check fails and comments the offending package, advisory, and license on the pull request.
2. Prove the gate works on a throwaway branch with a known vulnerable version.
npm install [email protected] && git commit -am 'test dependency gate' && git pushExpected output: The pull request check fails with the advisory identifier and the version that fixes it.
3. Confirm lockfile-only changes are still reviewed.
npm update --package-lock-only && git commit -am 'refresh lockfile' && git pushExpected output: Dependency review still runs, reports the changed transitive versions, and fails if a new vulnerable version appears.
4. Require the check in branch protection so merging waits for it.
Expected output: The merge button stays disabled until dependency review passes on the latest commit.
Troubleshooting
Problem
The action is skipped on some pull requests
Solution
Fork and Dependabot pull requests have restricted tokens; grant pull-requests: write and check the run log for permission errors.
Problem
No dependencies are detected
Solution
The action reads the dependency graph; unsupported manifest types produce an empty diff. Add a scanner job for those ecosystems.
Limitations
- Only changes introduced by the pull request are reviewed; existing vulnerable dependencies remain until updated.
- Coverage depends on GitHub's advisory database and can lag upstream disclosures.
Catch the diff, not the whole tree
Most dependency incidents enter through a small change: a version bump, a new dev tool, or a transitive package pulled in by a minor upgrade. Reviewing the entire dependency tree on every pull request produces noise and slow builds; reviewing the diff is fast and directly actionable. GitHub dependency review compares the base and head dependency graphs, then reports new vulnerable packages and license changes in the pull request itself. The comment lands where the author is already looking, which is the whole point.
Set a policy, not a vibe
Pick a severity floor and a license denylist, write both into the workflow, and keep them in review. fail-on-severity: high blocks high and critical advisories while allowing moderate findings to be tracked; denying GPL and AGPL protects a distributed product from obligations nobody agreed to. When a finding must be accepted, record it as a reviewed exception in the repository, not by changing the workflow to warn-only, because a warn-only gate is indistinguishable from no gate after a month.
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
deny-licenses: GPL-3.0, AGPL-3.0
Verify the failure path
Install a package version with a known advisory on a scratch branch and confirm the check fails, the comment names the advisory, and merging is blocked. Also test a lockfile-only refresh, since transitive updates are the case people forget. If both paths work, the gate is doing its job; if the check is missing from the pull request entirely, the repository’s dependency graph or token permissions are the first things to inspect.