Skip to content

feat(workflows): add gitleaks binary-based secret scanning as PR gate #260

@WilliamBerryiii

Description

@WilliamBerryiii

Summary

GitHub native secret scanning runs asynchronously after pushes and does not block PRs. This creates a gap where secrets could be merged before detection. We previously attempted to use gitleaks-action but removed it due to licensing requirements (commit 96c94de). The gitleaks binary itself is MIT licensed and can be used directly without a license.

Background

Current State

  • GitHub native secret scanning: ✅ Enabled (async, post-push alerts only)
  • PR-blocking secret detection: ❌ Not implemented
  • gitleaks-action: Removed at b930aa2 (required commercial license)
  • gitleaks binary: Available in dev container with SHA256 verification

Historical Context

96c94de refactor(security): replace gitleaks-action with reusable workflow
        "remove dependency on gitleaks-action (requires license)"
        "uses direct gitleaks binary (v8.29.0, no license required)"

b930aa2 fix(build): remove references to non-existent gitleaks and checkov workflows
        "workflows now reference only existing reusable workflows"

The reusable workflow was created but later removed because it didn't exist or wasn't functioning correctly.

Proposal

Implement gitleaks binary-based secret scanning that blocks PRs containing secrets.

Implementation Options

Option A: Dedicated Reusable Workflow

Create .github/workflows/gitleaks-scan.yml as a reusable workflow:

name: Gitleaks Secret Scan

on:
  workflow_call:
    inputs:
      soft-fail:
        description: 'Continue on detection (warning only)'
        type: boolean
        default: false

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          
      - name: Download gitleaks
        run: |
          VERSION="8.21.2"
          SHA256="4ddbe3b7779545759891d636413a2b932c676c67"
          curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${VERSION}/gitleaks_${VERSION}_linux_x64.tar.gz" -o gitleaks.tar.gz
          echo "${SHA256}  gitleaks.tar.gz" | sha256sum -c -
          tar -xzf gitleaks.tar.gz gitleaks
          
      - name: Run gitleaks
        run: ./gitleaks detect --source . --verbose --redact

Called from pr-validation.yml:

gitleaks-scan:
  uses: ./.github/workflows/gitleaks-scan.yml
  with:
    soft-fail: false

Option B: Inline Job in PR Validation

Add directly to .github/workflows/pr-validation.yml:

gitleaks:
  name: Secret Detection
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    - name: Run gitleaks
      run: |
        curl -sSfL https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz | tar -xz
        ./gitleaks detect --source . --verbose --redact

Recommendation

Option A (Reusable Workflow) is preferred because:

  • Consistent with existing workflow patterns (codeql-analysis.yml, etc.)
  • Allows soft-fail toggle for gradual rollout
  • Can be called from both pr-validation.yml and main.yml
  • Easier to maintain version/checksum updates in one place

Acceptance Criteria

  • gitleaks binary downloaded with SHA256 verification (use scripts/security/tool-checksums.json)
  • Workflow runs on pull_request events targeting main
  • Workflow fails PR if secrets detected (non-soft-fail mode)
  • SARIF output uploaded to GitHub Security tab (optional enhancement)
  • Update tool-checksums.json with current gitleaks version/SHA
  • Update threat model VM-2 control to reflect implementation accurately

References

  • gitleaks releases (MIT license)
  • Existing checksum infrastructure: scripts/security/tool-checksums.json
  • Dev container gitleaks install: .devcontainer/scripts/on-create.sh
  • Threat model control VM-2: docs/security/threat-model.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecuritySecurity-related changes or concerns

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions