Configuring Dependabot version and security updates Jump to heading

Dependabot does two different jobs that teams often conflate. Security updates open pull requests when a dependency you use has a published advisory, regardless of schedule. Version updates keep dependencies current on a schedule you choose, whether or not anything is vulnerable. Both are driven by the same .github/dependabot.yml, and the defaults β€” one pull request per dependency, every day, for every ecosystem β€” produce a flood that teams soon learn to ignore, which defeats the point. A deliberate configuration produces a manageable stream: grouped updates, sensible schedules, limits, and clear ownership. This page writes that configuration, within automated dependency updates.

When to use this approach Jump to heading

  • Your repositories are on GitHub and you want automated dependency pull requests.
  • Dependabot is enabled but its pull requests are ignored because there are too many.
  • You need security fixes to arrive quickly even if routine updates are batched.
  • You use Renovate elsewhere; its monorepo setup is covered in configuring Renovate for a monorepo.

Step 1 β€” Separate security updates from version updates Jump to heading

Security updates are enabled in repository settings and use the advisory database; they do not need a schedule. Version updates are configured in dependabot.yml. Turn both on, and treat them differently: security updates fast and individual, version updates batched and scheduled.

# Enable Dependabot alerts and security updates for a repository
gh api -X PUT "repos/$OWNER/$REPO/vulnerability-alerts"
gh api -X PUT "repos/$OWNER/$REPO/automated-security-fixes"
Security updates against version updatesSecurity updates are triggered by advisories against dependencies you use, arrive as soon as a fix exists, and should be reviewed quickly. Version updates are triggered by a schedule, keep everything current whether vulnerable or not, and are best grouped into a few pull requests.Security updatesVersion updatestriggerpublished advisoryscheduleconfigured inrepo settingsdependabot.ymltimingimmediatelyweekly / monthlyhandlingfast, individualgrouped, batchedbatching version updates is what makes the security ones stand out

Step 2 β€” Write a version-update configuration per ecosystem Jump to heading

Each updates entry covers one package ecosystem in one directory. List every ecosystem the repository uses, including GitHub Actions, which is often forgotten.

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule: { interval: weekly, day: monday, time: "05:30", timezone: Europe/Copenhagen }
    open-pull-requests-limit: 5
    groups:
      dev-dependencies:
        dependency-type: development
        update-types: [minor, patch]
      production-minor:
        dependency-type: production
        update-types: [minor, patch]
  - package-ecosystem: pip
    directory: "/services/billing"
    schedule: { interval: weekly, day: monday }
    groups:
      python-minor: { update-types: [minor, patch] }
  - package-ecosystem: github-actions
    directory: "/"
    schedule: { interval: monthly }
    groups:
      actions: { patterns: ["*"] }

Groups combine many updates into one pull request. Leaving major updates out of the groups means each major version arrives as its own pull request, where it can be reviewed properly β€” see handling major version upgrades from update bots.

Step 3 β€” Ignore what you do not want, explicitly Jump to heading

Some updates should never be proposed: a library pinned for compatibility, a major version you have decided to skip. Use ignore with a comment explaining why, so the rule can be revisited.

    ignore:
      # Pinned: v5 drops Node 18, which production still runs (revisit Q1)
      - dependency-name: "some-sdk"
        update-types: ["version-update:semver-major"]
      # Generated client; updated by the codegen job, not by hand
      - dependency-name: "@acme/api-client"
From a new release to a pull requestDependabot checks each configured ecosystem on its schedule, drops updates matched by ignore rules, groups the remaining minor and patch updates into a few pull requests, opens majors individually, and respects the open pull request limit.Scheduleper ecosystemNew versionsregistry checkignore rulespinned, skippedgroupsminor + patchPull requestslimit respectedmajors bypass the groups on purpose β€” they deserve their own review

Step 4 β€” Connect private registries Jump to heading

Updates for private packages need credentials for the registry. Define the registry once and reference it from each ecosystem entry; secrets come from Dependabot’s own secret store, not Actions secrets.

registries:
  npm-internal:
    type: npm-registry
    url: https://npm.pkg.example.com
    token: ${{ secrets.DEPENDABOT_NPM_TOKEN }}
updates:
  - package-ecosystem: npm
    directory: "/"
    registries: [npm-internal]
    schedule: { interval: weekly }
gh secret set DEPENDABOT_NPM_TOKEN --app dependabot < token.txt

Step 5 β€” Route pull requests to owners and keep CI honest Jump to heading

Dependency pull requests need reviewers who understand the affected code. Code owners handle that automatically when manifests are owned; labels make them easy to filter.

  - package-ecosystem: pip
    directory: "/services/billing"
    labels: [dependencies, billing]
    commit-message: { prefix: "chore(deps)", include: scope }

Dependabot’s pull requests run CI with restricted secrets, like pull requests from forks. Jobs that need secrets β€” integration tests against a staging service β€” will fail or be skipped. Decide which checks are required for dependency pull requests and make sure they can run without secrets, or use a follow-up workflow as described in running CI for fork pull requests safely.

Step 6 β€” Measure whether the stream is manageable Jump to heading

Track how many dependency pull requests are open and how long they wait. If the number grows week on week, the configuration is producing more than the team can review.

gh pr list --label dependencies --state open --json number,createdAt \
  --jq 'length as $n | (map(now - (.createdAt | fromdateiso8601)) | add / length / 86400) as $age |
        "\($n) open, average age \($age | floor) days"'
Dependency pull requests per week, before and after groupingAn illustrative repository with three ecosystems. With defaults, Dependabot opened a pull request per dependency and the team fell behind. With grouping and weekly schedules, the weekly count dropped to a handful that could be reviewed the same day.dependency PRs opened per week (illustrative)defaults34weekly schedule19+ groups5the goal is a number the team actually reviews, not zero

Validation checklist Jump to heading

Frequently Asked Questions Jump to heading

Should security updates also be grouped? Jump to heading

Dependabot can group security updates, which helps when one advisory affects many packages. Keep them separate from version-update groups, so a security fix is never stuck behind an unrelated breaking change.

Can Dependabot auto-merge? Jump to heading

Not on its own; it opens pull requests. Auto-merging safe updates with a workflow and required checks is covered in auto-merging patch updates safely.

Why does Dependabot not update our lockfile-only dependencies? Jump to heading

Version updates target direct dependencies by default. Transitive dependencies are updated when a direct one changes, or through security updates when a transitive package has an advisory.