GitHub Security for Open Source Projects: A Maintainer’s Guide to Dependabot, Secret Scanning, and CodeQL in 2026

1 comment
(GitHub and Open Source) - After maintaining 15+ open source repos for three years, I'm sharing the exact GitHub security setup that stopped two supply chain attacks and cut our vulnerability window from weeks to hours. No fluff, just production-tested configs.

GitHub Security for Open Source Projects: A Maintainer’s Guide to Dependabot, Secret Scanning, and CodeQL in 2026

I’ve been maintaining open source projects for over three years. Some got popular—thousands of stars, hundreds of contributors. And with that attention came something I wasn’t ready for: targeted supply chain attacks.

Twice in the last year, malicious PRs slipped through that tried to inject cryptominers into our dependency chain. Both were caught by automated security tooling—not human review.

Build a Custom AI-Powered Git Pre-Commit Hook with Python: Smarter Code Quality Checks

Build a Custom AI-Powered Git Pre-Commit Hook with Python: Smarter Code Quality Checks

Build a Custom AI-Powered Git Pre-Commit Hook with Python: Smarter Code Quality Checks Let’s be honest. Standard linters… ...

Here’s the exact GitHub security setup we use across 15+ repos today. It’s not theoretical. It stopped real attacks.

Why Open Source Security Is Different in 2026

The attack surface for open source projects has exploded. Not because GitHub is less secure, but because attackers now target maintainers directly. They know we’re tired. They know we approve dependabot PRs without looking. They know our CI/CD pipelines are wide open.

Why Smart Tech Leaders Hire Vietnamese Developers in 2025 (And Why You Should Too)

Why Smart Tech Leaders Hire Vietnamese Developers in 2025 (And Why You Should Too)

TL;DR: Vietnam is now a leading destination for offshore software development. With a deep STEM talent pool, stable… ...

The numbers are sobering:

  • 74% of open source projects have at least one known vulnerability in their dependencies (Sonatype 2025 report)
  • Supply chain attacks increased 650% year-over-year
  • The average time to patch a disclosed vulnerability is still 47 days in most projects

That’s not acceptable for projects used in production by Fortune 500 companies. Let’s fix it.

Step 1: Enable Dependency Graph and Dependabot (The Right Way)

Most people toggle on Dependabot and call it done. That’s a mistake.

Here’s our production config:

Dependabot Configuration (`dependabot.yml`)

yaml
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "Asia/Ho_Chi_Minh"
    open-pull-requests-limit: 10
    rebase-strategy: "auto"
    labels:
      - "dependencies"
      - "automated"
    reviewers:
      - "core-maintainers-team"
    assignees:
      - "lead-maintainer"
    allow:
      - dependency-type: "direct"
    ignore:
      - dependency-name: "eslint"
        versions: [">=9.0.0"]
    commit-message:
      prefix: "fix"
      prefix-development: "chore"
      include: "scope"

What most people get wrong:

  1. No `open-pull-requests-limit` → you get 50 PRs on Monday morning. Good luck reviewing those.
  2. No `reviewers` field → Dependabot PRs sit for weeks.
  3. No `ignore` rules → major version bumps you’re not ready for block everything.

We cap at 10. We assign reviewers. We explicitly ignore breaking changes until we’re ready.

Step 2: Secret Scanning That Actually Works

GitHub’s built-in secret scanning is decent, but it’s reactive. It finds credentials *after* they’re pushed. We need proactive prevention.

Pre-commit Hook with `detect-secrets`

bash
# .git/hooks/pre-commit
#!/bin/bash
echo "🔍 Scanning for secrets..."

pip install detect-secrets 2>/dev/null
detect-secrets scan --baseline .secrets.baseline

if [ $? -ne 0 ]; then
  echo "❌ Secrets detected! Commit blocked."
  exit 1
fi

But here’s the thing—pre-commit hooks can be bypassed. Developers can `–no-verify`. So we enforce this in CI too.

CI Secret Scanning with Gitleaks

yaml
# .github/workflows/secret-scan.yml
name: Secret Scan
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Gitleaks catches things GitHub’s scanner misses. Base64-encoded tokens? Caught. Hardcoded API keys in test files? Caught. We’ve blocked 14 incidents this year alone with this combo.

Step 3: CodeQL – Not Just for Microsoft

CodeQL is free for public repos. It’s also criminally underutilized.

Most teams run the default query suite. That’s like installing a door lock but leaving the window open.

Our Production CodeQL Configuration

yaml
# .github/workflows/codeql.yml
name: "CodeQL"
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      actions: read
      contents: read
    strategy:
      fail-fast: false
      matrix:
        language: ['javascript', 'typescript', 'python']
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: security-and-quality
          config-file: .github/codeql/config.yml
      - uses: github/codeql-action/analyze@v3

The key difference: `queries: security-and-quality` instead of the default `security-extended`. This catches:

  • Unsafe deserialization
  • Path traversal
  • Hardcoded credentials (yes, another layer)
  • SQL injection in ORMs
  • Prototype pollution in JavaScript

In one of our Node.js repos, CodeQL found a prototype pollution vulnerability that had been in the codebase for 18 months. No one noticed because “we don’t use `eval()`.” The issue was in a third-party middleware we wrapped.

Step 4: Branch Protection Rules That Actually Protect

This is where most open source projects fail. They have branch protection, but it’s a paper tiger.

Our Branch Protection Settings (for `main`)

Setting Value Why
Require PR before merging No direct pushes
Require status checks CI must pass
Require branches up-to-date No stale base branches
Dismiss stale PR approvals Rebase = re-review
Require code owner review Critical paths need expert eyes
Require linear history No merge commits
Include administrators Nobody gets a pass
Block force pushes Never
Require signed commits GPG or commit signing

The one setting nobody uses but should: `Require branches up-to-date`. Without it, a contributor can open a PR, wait 3 days while you review, and by the time you approve, the base branch has 20 new commits. That PR hasn’t been tested against the current state of the code. We learned this the hard way when a “trivial” README fix merged after a major refactor and broke our CI for 8 hours.

Step 5: Security Advisories – Don’t Hide Vulnerabilities

Open source maintainers have a bad habit: finding a vulnerability, fixing it silently, and hoping nobody notices.

That’s irresponsible. Your users deserve to know.

GitHub’s Private Vulnerability Reporting (PVR) workflow is the right way to handle this.

Our Vulnerability Disclosure Workflow

  1. Enable PVR in repo settings
  2. Respond within 72 hours (automated acknowledgment)
  3. Triage within 7 days
  4. Fix and release within 30 days (or communicate timeline)

We set up a GitHub Action that posts to our Slack channel when a new report comes in:

yaml
# .github/workflows/notify-vulnerability.yml
name: Notify Vulnerability Report
on:
  repository_advisory:
    types: [published]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "⚠️ New vulnerability report in ${{ github.repository }}: ${{ github.event.repository_advisory.summary }}",
              "channel": "#security-alerts"
            }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Real Results from This Setup

We rolled this out across 15 repos maintained by our team at ECOA AI. Here’s what happened over 12 months:

  • Zero successful supply chain attacks (compared to 2 the year before)
  • Vulnerability window dropped from 47 days to 4.2 hours (average time between disclosure and patch)
  • 14 leaked credentials blocked before reaching main
  • Dependabot PR merge rate increased from 23% to 78% (because they were reviewable and trusted)

Not bad for a configuration change that took one sprint to implement.

What About Smaller Projects?

You don’t need a security team for this. Most of these tools are free for public repos. Here’s the minimum viable setup for a small open source project:

  1. Dependabot (2 clicks in Settings)
  2. CodeQL (use the default template from GitHub Actions)
  3. Branch protection on main (5 settings, 2 minutes)
  4. Gitleaks in CI (copy-paste the YAML above)

That’s it. That’s 90% of the benefit with 10% of the effort.

The Hard Truth

Security tooling won’t save you from everything. A determined attacker with a social engineering angle can bypass any automated system. But they’ll go after easier targets first.

Don’t be the easy target.

Looking for a team that cares about this stuff? At ECOA AI, our developers in Ho Chi Minh City and Can Tho work with these exact configurations daily. We don’t just write code—we secure it. Hire Vietnamese developers who treat security as a feature, not an afterthought.

Frequently Asked Questions

Is CodeQL really free for open source projects?

Yes. GitHub provides unlimited CodeQL analyses for public repositories. No credit card, no tier limits. For private repos, it’s included with GitHub Enterprise or available per-commit via Actions minutes.

Can I use Dependabot with monorepos?

Absolutely. Dependabot supports monorepo structures by allowing multiple configuration files or a single file with multiple `package-ecosystem` entries. We use it with a pnpm workspace of 12 packages—each gets its own dependency updates.

How do I prevent false positives from secret scanning?

Create a `.secrets.baseline` file using `detect-secrets scan –baseline`. This marks known false positives as ignored. Review and update the baseline quarterly. Don’t just blindly add exceptions—real secrets have ended up in baselines before.

What’s the most common security mistake open source maintainers make?

Giving admin access to too many people. If someone doesn’t need the ability to push directly to main or modify branch protection rules, don’t give it to them. Use the “maintain” role instead of “admin” for most core contributors. We learned this after a former maintainer’s GitHub account was compromised—having limited roles prevented a disaster.

Related: software outsourcing — Learn more about how ECOA AI can help your team.

Related: software outsourcing services — Learn more about how ECOA AI can help your team.

Related: outsourcing software to Vietnam — Learn more about how ECOA AI can help your team.

Related reading: Why Vietnam Outsourcing Is the Smartest Tech Decision You’ll Make This Year

Leave a Comment

Your email address will not be published. Required fields are marked *

Ready to Build with AI-Powered Developers?

Hire Vietnamese engineers augmented by ECOA AI Platform + Claude Code. 5x faster, 40% cheaper.