How-To Guide

Setting Up Dependency Scanning on GitHub

A hands-on walkthrough for configuring automated dependency scanning in your GitHub repositories, from Dependabot alerts to custom CI workflows.

James
Senior DevOps Engineer
6 min read

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:

  1. Dependency Graph - Automatically parses your manifests and lock files to map your dependency tree.
  2. Dependabot Alerts - Matches your dependency graph against the GitHub Advisory Database.
  3. 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:

  1. Go to your repository Settings.
  2. Navigate to Code security and analysis.
  3. 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:

  1. Generates an SBOM from your project.
  2. Scans it against vulnerability databases.
  3. Fails the build if high or critical vulnerabilities are found.
  4. 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:

  1. Go to Settings, then Branches.
  2. Add a rule for main.
  3. Enable "Require status checks to pass before merging."
  4. 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.

Never miss an update

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