Home/Blog/GitHub Repository Security: Branch Protection, Dependabot, and Access Control
Software Engineering

GitHub Repository Security: Branch Protection, Dependabot, and Access Control

Secure your GitHub repositories with branch protection rules, CODEOWNERS, Dependabot, secret scanning, security policies, and access control best practices.

By Inventive HQ Team
GitHub Repository Security: Branch Protection, Dependabot, and Access Control

Your GitHub repository is more than code—it's intellectual property, deployment pipelines, and access to production systems. A single compromised repository can lead to supply chain attacks affecting thousands of users. This guide covers essential security configurations every repository should have.

Security Configuration Overview

┌─────────────────────────────────────────────────────────────┐
│                 REPOSITORY SECURITY LAYERS                   │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   ┌──────────────────────────────────────────────────────┐  │
│   │                   ACCESS CONTROL                      │  │
│   │  • Repository visibility (public/private/internal)    │  │
│   │  • Team permissions (read/write/maintain/admin)       │  │
│   │  • Outside collaborators                              │  │
│   │  • 2FA requirements                                   │  │
│   └──────────────────────────────────────────────────────┘  │
│                          │                                   │
│                          ▼                                   │
│   ┌──────────────────────────────────────────────────────┐  │
│   │                BRANCH PROTECTION                      │  │
│   │  • Required reviews                                   │  │
│   │  • Required status checks                             │  │
│   │  • Prevent force push                                 │  │
│   │  • Require signed commits                             │  │
│   └──────────────────────────────────────────────────────┘  │
│                          │                                   │
│                          ▼                                   │
│   ┌──────────────────────────────────────────────────────┐  │
│   │                 CODE SECURITY                         │  │
│   │  • Secret scanning                                    │  │
│   │  • Dependabot alerts                                  │  │
│   │  • Code scanning (CodeQL)                            │  │
│   │  • Dependency review                                  │  │
│   └──────────────────────────────────────────────────────┘  │
│                          │                                   │
│                          ▼                                   │
│   ┌──────────────────────────────────────────────────────┐  │
│   │                  AUDIT & POLICY                       │  │
│   │  • Security policy (SECURITY.md)                     │  │
│   │  • Audit log                                          │  │
│   │  • Repository rules                                   │  │
│   └──────────────────────────────────────────────────────┘  │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Branch Protection Rules

Branch protection prevents accidental or malicious changes to critical branches.

Essential Configuration

Navigate to Settings > Branches > Add branch protection rule:

Branch name pattern: main
(also consider: release/*, develop)

┌─────────────────────────────────────────────────────────────┐
│              RECOMMENDED PROTECTION RULES                    │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ☑ Require a pull request before merging                    │
│    ├── ☑ Required approving reviews: 1 (or 2 for critical) │
│    ├── ☑ Dismiss stale pull request approvals              │
│    ├── ☑ Require review from Code Owners                   │
│    └── ☑ Require approval of most recent push              │
│                                                              │
│  ☑ Require status checks to pass before merging             │
│    ├── ☑ Require branches to be up to date                 │
│    └── Status checks: ci/build, ci/test, security/scan     │
│                                                              │
│  ☑ Require conversation resolution before merging           │
│                                                              │
│  ☑ Require signed commits (if team uses GPG signing)       │
│                                                              │
│  ☑ Require linear history (forces squash or rebase)        │
│                                                              │
│  ☑ Do not allow force pushes                                │
│                                                              │
│  ☑ Do not allow deletions                                   │
│                                                              │
│  ☐ Restrict who can push (only for specific workflows)      │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Multiple Branch Patterns

# Production branch
main
├── 2 required reviewers
├── All status checks required
├── No force push
└── Code owner review required

# Development branch
develop
├── 1 required reviewer
├── Build and test checks required
└── Force push allowed for maintainers

# Release branches
release/*
├── 2 required reviewers
├── All checks including integration tests
├── No force push
└── Only release managers can push

# Feature branches
feature/*
├── No protection (developer freedom)
└── Deleted after merge

CODEOWNERS

CODEOWNERS automatically assigns reviewers based on file paths.

Setup

Create .github/CODEOWNERS:

# Default owners for everything
* @org/core-team

# Frontend team owns UI code
/src/components/ @org/frontend-team
/src/pages/ @org/frontend-team
/src/styles/ @org/frontend-team
*.tsx @org/frontend-team
*.css @org/frontend-team

# Backend team owns API code
/src/api/ @org/backend-team
/src/services/ @org/backend-team
/src/models/ @org/backend-team

# DevOps owns infrastructure
/terraform/ @org/devops-team
/kubernetes/ @org/devops-team
/.github/workflows/ @org/devops-team
Dockerfile @org/devops-team

# Security team must review security-sensitive code
/src/auth/ @org/security-team @org/backend-team
/src/crypto/ @org/security-team
/src/permissions/ @org/security-team

# Specific file owners
package.json @lead-developer
package-lock.json @lead-developer
/docs/ @technical-writer

CODEOWNERS Rules

PatternMatchesOwner
*All files (default)Fallback owner
/docs/docs/ directory onlySpecific path
*.jsAll JS files anywhereExtension-based
/src/**/*.test.tsTest files in srcNested pattern
@org/teamGitHub teamTeam ownership
@usernameIndividual userPerson ownership

Enable enforcement in branch protection:

  • Check "Require review from Code Owners"
  • Set required reviewers to at least 1

Dependabot Configuration

Dependabot keeps dependencies updated and alerts on vulnerabilities.

Enable Dependabot

Settings > Code security and analysis:

  • ☑ Dependency graph
  • ☑ Dependabot alerts
  • ☑ Dependabot security updates
  • ☑ Dependabot version updates (optional)

Configuration File

Create .github/dependabot.yml:

version: 2
updates:
  # NPM dependencies
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "09:00"
      timezone: "America/New_York"
    open-pull-requests-limit: 10
    reviewers:
      - "org/frontend-team"
    labels:
      - "dependencies"
      - "automated"
    commit-message:
      prefix: "chore(deps):"
    ignore:
      - dependency-name: "typescript"
        versions: ["5.x"]  # Stay on 4.x for now
    groups:
      dev-dependencies:
        patterns:
          - "@types/*"
          - "eslint*"
          - "prettier"
        update-types:
          - "minor"
          - "patch"

  # Python dependencies
  - package-ecosystem: "pip"
    directory: "/backend"
    schedule:
      interval: "weekly"
    reviewers:
      - "org/backend-team"

  # Docker base images
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
    reviewers:
      - "org/devops-team"

  # GitHub Actions
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    reviewers:
      - "org/devops-team"

Grouping Updates

Reduce PR noise by grouping related updates:

groups:
  # Group all eslint-related updates
  linting:
    patterns:
      - "eslint*"
      - "@typescript-eslint/*"
      - "prettier"

  # Group AWS SDK updates
  aws-sdk:
    patterns:
      - "@aws-sdk/*"

  # Group testing libraries
  testing:
    patterns:
      - "jest"
      - "@testing-library/*"
      - "vitest"

Secret Scanning

Secret scanning detects accidentally committed credentials.

Enable Secret Scanning

Settings > Code security and analysis:

  • ☑ Secret scanning
  • ☑ Push protection (blocks pushes containing secrets)

Supported Secret Types

GitHub detects 100+ secret formats including:

ProviderSecret Types
AWSAccess keys, secret keys
AzureConnection strings, tokens
GCPAPI keys, service accounts
GitHubPersonal access tokens, OAuth
SlackBot tokens, webhooks
StripeAPI keys (test and live)
TwilioAPI keys, auth tokens
DatabaseConnection strings

Custom Patterns (Enterprise)

Define custom secret patterns for internal credentials:

# Settings > Code security > Secret scanning > Custom patterns
name: Internal API Key
pattern: INTERNAL_API_[A-Z0-9]{32}

Handling Detected Secrets

┌─────────────────────────────────────────────────────────────┐
│              SECRET DETECTION RESPONSE                       │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   1. IMMEDIATE: Rotate the credential                       │
│      └── Don't wait—assume it's compromised                 │
│                                                              │
│   2. INVESTIGATE: Check for unauthorized use                │
│      ├── Provider access logs (AWS CloudTrail, etc.)        │
│      └── Application audit logs                             │
│                                                              │
│   3. REMEDIATE: Remove from repository                      │
│      ├── For public repos: history rewrite required         │
│      └── For private repos: assess risk                     │
│                                                              │
│   4. PREVENT: Add pre-commit scanning                       │
│      └── git-secrets, gitleaks, detect-secrets              │
│                                                              │
│   5. RESOLVE: Mark alert as resolved in GitHub             │
│      └── Select resolution reason                           │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Code Scanning (CodeQL)

CodeQL performs semantic code analysis to find vulnerabilities.

Enable Code Scanning

Settings > Code security and analysis > Code scanning:

  • Click "Set up" > "Default" for automatic configuration
  • Or "Advanced" for custom workflow

CodeQL Workflow

# .github/workflows/codeql.yml
name: "CodeQL"

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'  # Weekly Monday 6 AM

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      packages: read
      actions: read
      contents: read

    strategy:
      fail-fast: false
      matrix:
        language: ['javascript', 'python']

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          queries: security-extended,security-and-quality

      - name: Autobuild
        uses: github/codeql-action/autobuild@v3

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{matrix.language}}"

Security Policies

SECURITY.md

Create SECURITY.md in repository root:

# Security Policy

## Supported Versions

| Version | Supported          |
| ------- | ------------------ |
| 2.x.x   | :white_check_mark: |
| 1.x.x   | :white_check_mark: |
| < 1.0   | :x:                |

## Reporting a Vulnerability

**Please do not report security vulnerabilities through public GitHub issues.**

Instead, please report them via email to [email protected].

Include:
- Type of issue (buffer overflow, SQL injection, XSS, etc.)
- Full paths of source file(s) related to the issue
- Location of affected source code (tag/branch/commit or direct URL)
- Step-by-step instructions to reproduce
- Proof-of-concept or exploit code (if possible)
- Impact of the issue

## Response Timeline

- **Acknowledgment**: Within 48 hours
- **Initial Assessment**: Within 1 week
- **Fix Development**: Varies by severity
- **Disclosure**: Coordinated with reporter

## Bug Bounty

We do not currently offer a bug bounty program.

## Security Measures

This repository implements:
- Branch protection rules
- Required code reviews
- Automated security scanning
- Dependency updates via Dependabot

Private Vulnerability Reporting

Enable private vulnerability reporting:

Settings > Code security and analysis:

  • ☑ Private vulnerability reporting

Contributors can now report vulnerabilities privately through GitHub's Security tab.

Access Control

Repository Permissions

RoleCapabilities
ReadClone, view code, open issues
TriageManage issues and PRs (no code push)
WritePush to non-protected branches
MaintainManage repo settings (no admin)
AdminFull access including dangerous actions

Team-Based Access

Organization: example-org
│
├── @example-org/core-team (Admin)
│   └── All repositories
│
├── @example-org/backend-team (Write)
│   └── api-service, data-service
│
├── @example-org/frontend-team (Write)
│   └── web-app, mobile-app
│
├── @example-org/devops-team (Maintain)
│   └── All repositories (for CI/CD)
│
└── @example-org/contractors (Read)
    └── Documentation repositories only

Organization Settings

Settings > Member privileges:

  • Base permissions: Read (minimal by default)
  • Repository creation: Disabled for members
  • Repository forking: Private repos disabled
  • Pages creation: Restricted

Settings > Security:

  • ☑ Require 2FA for all members
  • ☐ Allow forking of private repositories
  • ☑ Base permissions: Read

Audit and Monitoring

Audit Log

Access via Settings > Audit log or API:

# Export audit log via API
gh api /orgs/{org}/audit-log \
  --paginate \
  -H "Accept: application/json" \
  > audit-log.json

Key events to monitor:

EventSignificance
repo.createNew repository created
protected_branch.*Branch protection changed
org.add_memberNew organization member
repo.accessRepository visibility changed
secret_scanning_alert.*Secret detected

Security Overview (Organizations)

Organization > Security > Overview:

  • View all security alerts across repos
  • Track Dependabot alerts
  • Monitor secret scanning
  • Code scanning results

Webhook Monitoring

Set up webhooks for security events:

{
  "name": "web",
  "active": true,
  "events": [
    "branch_protection_rule",
    "code_scanning_alert",
    "dependabot_alert",
    "member",
    "membership",
    "repository",
    "repository_vulnerability_alert",
    "secret_scanning_alert",
    "security_and_analysis",
    "team"
  ],
  "config": {
    "url": "https://your-security-dashboard.com/github-webhook",
    "secret": "your-webhook-secret",
    "content_type": "json"
  }
}

Quick Reference

Security Checklist

Repository Setup
☐ Enable secret scanning
☐ Enable Dependabot alerts
☐ Enable Dependabot security updates
☐ Configure branch protection for main
☐ Create SECURITY.md
☐ Set up CODEOWNERS

Branch Protection (main)
☐ Require pull request reviews
☐ Require status checks
☐ Require up-to-date branches
☐ Require code owner review
☐ Disable force push
☐ Disable branch deletion

Access Control
☐ Use team-based permissions
☐ Require 2FA for organization
☐ Set minimal base permissions
☐ Audit outside collaborators quarterly

Monitoring
☐ Enable audit log forwarding
☐ Set up security alert notifications
☐ Review security overview weekly

Let's turn this knowledge into action

Get a free 30-minute consultation with our experts. We'll help you apply these insights to your specific situation.