GitHub gives you several built-in options for dependency scanning, and most teams only use a fraction of what is available. In this guide, I will walk through setting up a comprehensive dependency scanning pipeline on GitHub, from the zero-config basics to custom workflows that give you real control.
The Three Layers of GitHub Dependency Scanning
GitHub offers three complementary features:
- Dependency Graph - Automatically parses your manifests and lock files to map your dependency tree.
- Dependabot Alerts - Matches your dependency graph against the GitHub Advisory Database.
- Dependabot Security Updates - Automatically opens PRs to fix vulnerable dependencies.
Most repositories have the dependency graph enabled by default. The other two need explicit activation.
Step 1: Enable the Dependency Graph
For public repositories, this is already on. For private repositories:
- Go to your repository Settings.
- Navigate to Code security and analysis.
- Enable Dependency graph.
The dependency graph supports package manifests for npm, pip, Maven, Gradle, NuGet, Cargo, Go modules, and several others. It reads package-lock.json, requirements.txt, pom.xml, and similar files to build a complete picture of your dependencies.
One important note: the dependency graph only reads committed lock files. If your lock file is in .gitignore, the graph will only see your manifest file, which means it will miss pinned versions and transitive dependencies.
Step 2: Enable Dependabot Alerts
Same settings page, flip the switch for Dependabot alerts. Once enabled, GitHub will:
- Scan your dependency graph against the GitHub Advisory Database (GHSA).
- Create alerts for any known vulnerabilities.
- Notify repository administrators via email and the Security tab.
Alerts include the CVE identifier, severity, affected version range, and patched version when available.
Configuring Alert Notifications
By default, alerts notify repository admins. For teams, you want broader visibility. Configure notifications under your personal settings or set up a team webhook:
# .github/dependabot.yml is for updates, not alerts
# Alert notifications are configured in repository settings
For Slack or Teams notifications, use GitHub's webhook integration or a GitHub Action that posts to your channel when new alerts appear.
Step 3: Enable Dependabot Security Updates
This is where the automation kicks in. Enable Dependabot security updates, and GitHub will automatically open PRs to bump vulnerable dependencies to their minimum patched version.
These PRs include:
- The specific vulnerability being addressed.
- Release notes for the updated package.
- Compatibility score based on CI pass rates across other repositories.
The compatibility score is genuinely useful. If 95% of other projects that made the same upgrade had their tests pass, you can merge with higher confidence.
Step 4: Configure Dependabot Version Updates
Security updates only trigger when a vulnerability is known. Version updates proactively keep your dependencies current, reducing the blast radius when vulnerabilities are eventually found.
Create .github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "America/New_York"
open-pull-requests-limit: 10
reviewers:
- "your-team/security"
labels:
- "dependencies"
- "automated"
commit-message:
prefix: "deps"
ignore:
# Ignore major version updates for stability
- dependency-name: "*"
update-types: ["version-update:semver-major"]
groups:
# Group minor/patch updates to reduce PR noise
minor-and-patch:
update-types:
- "minor"
- "patch"
Key configuration choices:
- Schedule weekly, not daily. Daily creates too many PRs and causes review fatigue.
- Group updates. Grouping minor and patch updates into single PRs dramatically reduces noise.
- Ignore major versions. Major updates often include breaking changes. Handle those manually.
- Set a PR limit. Ten open PRs is manageable. Fifty is not.
Step 5: Add a Custom Scanning Workflow
Dependabot is great for known vulnerabilities in package manifests, but it has blind spots. For deeper scanning, add a GitHub Actions workflow:
name: Dependency Security Scan
on:
pull_request:
branches: [main]
push:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6 AM
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v3
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
format: cyclonedx-json
output-file: sbom.json
- name: Scan for vulnerabilities
uses: anchore/scan-action@v3
id: scan
with:
sbom: sbom.json
fail-build: true
severity-cutoff: high
- name: Upload SARIF report
if: always()
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
This workflow:
- Generates an SBOM from your project.
- Scans it against vulnerability databases.
- Fails the build if high or critical vulnerabilities are found.
- Uploads results in SARIF format so they appear in GitHub's Security tab alongside Dependabot alerts.
Step 6: Set Branch Protection Rules
Scanning is useless if developers can merge without passing the checks. Configure branch protection on your main branch:
- Go to Settings, then Branches.
- Add a rule for
main. - Enable "Require status checks to pass before merging."
- Add your security scan job as a required check.
Now no code merges to main without passing the vulnerability scan.
Handling Alert Fatigue
The biggest failure mode is enabling everything and then ignoring the flood of alerts. Here is how to manage it:
Dismiss with reason. When dismissing an alert, always select a reason (not affected, inaccurate, tolerable risk). This builds institutional knowledge.
Create a triage rotation. Assign one team member per sprint to review and triage new Dependabot alerts. Rotate weekly.
Set SLAs by severity. Critical: 48 hours. High: 1 week. Medium: 1 month. Low: next quarterly maintenance window.
Use CODEOWNERS. Assign ownership of dependency files so the right team is automatically assigned to Dependabot PRs:
# .github/CODEOWNERS
package.json @your-org/frontend-team
requirements.txt @your-org/backend-team
go.mod @your-org/platform-team
Monitoring Your Security Posture
GitHub provides a Security Overview at the organization level that aggregates alerts across all repositories. Use it to track:
- Total open alerts by severity.
- Mean time to remediation.
- Repositories with the most unaddressed alerts.
Export this data regularly for your security metrics dashboard.
How Safeguard.sh Helps
While GitHub's built-in tools cover the basics, Safeguard.sh extends your GitHub dependency scanning with deeper analysis, cross-repository visibility, and policy enforcement that goes beyond what Dependabot offers. It integrates with your GitHub workflows, enriches findings with reachability analysis, and provides a centralized dashboard that aggregates risk across your entire GitHub organization. For teams outgrowing Dependabot's capabilities, Safeguard.sh fills the gaps without replacing what already works.