Dependabot: The Security Bot That Reviews PRs While You Sleep 🤖🔒
Dependabot: The Security Bot That Reviews PRs While You Sleep 🤖🔒
True story: I once inherited a Laravel monolith at work. First thing I did was run composer audit.
It output 47 known vulnerabilities.
Forty. Seven.
The previous team hadn't updated a dependency in 18 months. The app was basically a colander holding user data. 😬
That was my wake-up call to take dependency security seriously. And then I discovered Dependabot — and I realized I'd been doing this the hard way.
What Even Is Dependabot? 🤔
Dependabot is a GitHub-owned bot (acquired back in 2019) that does three things automatically:
1. Scans your dependencies for known CVEs
2. Opens PRs to update vulnerable packages
3. Keeps dependencies generally up-to-date
It's not magic. It's automation. The kind of automation that saves you from manually reading security advisories at 11pm because a client called panicking about a zero-day.
As a full-time developer who contributes to open source, I've seen Dependabot work both sides: as a maintainer receiving Dependabot PRs, and as a contributor to projects where Dependabot flags something I introduced. Both perspectives taught me a lot.
The Three Modes of Dependabot 🎛️
Before we go further, let's be clear — Dependabot has three distinct features that people often confuse:
🔒 Security Alerts (free, automatic)
GitHub silently watches your repo against the GitHub Advisory Database. When a CVE matches one of your dependencies, it notifies you in the Security tab.
This is passive. It tells you about problems. It doesn't fix them.
🔧 Security Updates (free, opt-in)
This is Dependabot actually doing work. When it spots a vulnerable dependency, it opens a PR with the minimum version bump needed to fix the CVE.
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
That config alone makes Dependabot start filing security PRs for your PHP project.
🔄 Version Updates (free, opt-in)
This goes beyond security — it keeps ALL your dependencies fresh, even if there's no CVE. Basically: "update everything to latest on a schedule."
This one is more aggressive. I recommend reading your project's breaking-change history before turning it on. Learned this the hard way. 🙃
My First Dependabot PR (And Why I Almost Rejected It) 😅
When I first enabled Dependabot on a personal Laravel project, I got a PR within 20 minutes:
🤖 Bump symfony/http-kernel from 5.4.2 to 5.4.38
Bumps symfony/http-kernel from 5.4.2 to 5.4.38.
Vulnerabilities fixed:
- CVE-2023-XXXX: GHSA-xxxxxx
Affected versions: < 5.4.38
Severity: High
...
My first instinct: "Who authorized this bot to touch my dependencies??"
My second instinct (after reading it): "Oh. That's a high-severity vulnerability I've been sitting on for eight months."
I merged it. It took 4 minutes. The alternative was not knowing about the CVE and running vulnerable code in production.
Balancing work and open source taught me this: you can't manually track every security advisory for every package you depend on. There are thousands of them. Bots exist for exactly this reason.
Setting It Up in 5 Minutes 🚀
For a standard Laravel/PHP project, drop this in .github/dependabot.yml:
version: 2
updates:
# Composer (PHP)
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"
- "security"
# Don't open PRs for dev dependencies
ignore:
- dependency-name: "phpunit/phpunit"
update-types: ["version-update:semver-major"]
# npm (if you also have frontend assets)
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
For Node.js only:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily" # npm ecosystem moves fast
groups:
# Group minor/patch updates together
minor-and-patch:
update-types:
- "minor"
- "patch"
The groups option is underrated. Without it, you get 12 separate PRs for 12 minor bumps. With it, one PR, one merge, done. 🎯
What Dependabot Can't Do (Be Honest About This) ⚠️
In the security community, there's a dangerous temptation to treat Dependabot as a full security solution. It's not. Here's what it misses:
✅ Dependabot catches:
- Known CVEs in direct dependencies
- Known CVEs in transitive dependencies (sometimes)
- Outdated packages with published advisories
❌ Dependabot misses:
- Zero-days (obviously — no advisory yet)
- Custom security issues in your own code
- Misconfiguration vulnerabilities
- Logic bugs that expose data
- Typosquatted packages you installed by mistake
- Dependencies without published CVEs that are still compromised
Dependabot is one layer. Layer it with npm audit, composer audit, Snyk, or OWASP Dependency-Check for proper coverage.
The Maintainer Side: Drowning in Bot PRs 😭
Here's something nobody warns you about: if you maintain a popular open source project and you haven't configured Dependabot well, you'll wake up to 30 Dependabot PRs on a Monday morning.
I maintain a small PHP security library. Last year, Dependabot opened 11 PRs in one day during a busy update cycle.
Each PR needs:
- Reading the changelog
- Checking for breaking changes
- Running the test suite
- Merging or explaining why not
At 10 minutes per PR, that's nearly 2 hours of work from a bot. 😤
The fix:
# Group all Dependabot PRs together where possible
updates:
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
groups:
all-dependencies:
patterns:
- "*"
# Only auto-merge patch updates via GitHub Actions
# (see auto-merge section below)
And then pair it with GitHub Actions auto-merge for patch-level security PRs:
# .github/workflows/dependabot-automerge.yml
name: Dependabot Auto-Merge
on: pull_request
permissions:
pull-requests: write
contents: write
jobs:
auto-merge:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2
- name: Auto-merge patch updates
if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Patch update? Auto-merged after CI passes. You don't even see it. Minor/major updates still get your eyes.
This saved me hours every month.
Dependabot in the Open Source World 🌍
As a full-time developer who contributes to open source, I've watched Dependabot reshape how maintainers handle security.
Before Dependabot went mainstream, the workflow was:
- A researcher publishes a CVE
- Someone emails the maintainer
- Maintainer reads the email (maybe)
- Maintainer opens a PR
- PR sits there for 3 months
Now:
- CVE gets added to GitHub Advisory Database
- Dependabot opens a PR within hours
- Maintainer sees a PR already prepped with the fix
- Merge takes 2 minutes
That's a massive improvement in ecosystem security. Projects that would've sat vulnerable for months get patched in days.
I've seen this in PHP/Laravel packages I contribute to. A CVE in a popular deserialization library got patched across 40+ dependent packages within a week because all of them had Dependabot enabled. That kind of coordinated, automated response wasn't possible before.
The Repos You Should Enable This On RIGHT NOW 📋
Quick audit checklist:
# Check if Dependabot is configured
ls .github/dependabot.yml
# Check current vulnerabilities
npm audit
composer audit
# Check when deps were last updated (npm)
npx npm-check-updates
# Check when deps were last updated (composer)
composer outdated
If dependabot.yml doesn't exist, add it. If npm audit or composer audit shows critical/high vulnerabilities, you have Dependabot's job piling up waiting for you manually.
The repos to prioritize:
- Production apps — obviously
- Open source libraries — your users depend on your dependency hygiene
- Internal tools with access to sensitive data — often the most neglected
- Old side projects — the ones you forgot about that still run on a server somewhere
Lessons From the Security Community 🛡️
In the security community, we have a saying: "Attackers know your CVE list before you do."
When a vulnerability is published, automated scanning tools pick it up immediately. If you're running a vulnerable version and it's publicly known, you're a target. Not hypothetically — actively targeted.
Dependabot closes that gap. It's not about being paranoid. It's about making the gap between "CVE published" and "patch deployed" as small as possible.
The teams I've seen get hit by dependency-related breaches had one thing in common: they knew about the vulnerability. They just hadn't gotten around to patching it.
"I'll do it next sprint" is not a security strategy.
TL;DR 💡
- Dependabot is a free GitHub bot that automatically opens PRs to fix vulnerable dependencies
- Set it up with
.github/dependabot.ymlin under 5 minutes - Use groups to avoid PR spam; use auto-merge for patch updates
- It covers known CVEs — pair it with
npm audit/composer auditfor full coverage - In open source, Dependabot has dramatically shortened the patch timeline for security issues
- "I'll do it next sprint" is how breaches happen
Your homework: Go check if .github/dependabot.yml exists in your most important repo. If it doesn't, add it tonight. Your future self (who doesn't want to explain a breach) will thank you.
Because running a dependency with a published CVE isn't bad luck. It's just not having a bot that was free the whole time. 🤖🔒
Running a project with Dependabot horror stories or wins? Find me on LinkedIn or GitHub. Always happy to compare "how many CVEs did you inherit this week" notes.
The best security patch is the one you didn't have to remember to write. 🛡️