Skip to content
Security Beginner Tutorial

Block Secrets Before They Hit GitHub with Gitleaks

Set up a Gitleaks pre-commit hook and GitHub Actions check that reject commits containing credentials.

Emeka Okafor
Emeka Okafor
Security Editor · Jul 27, 2026 · 4 min read
Block Secrets Before They Hit GitHub with Gitleaks

What you'll build

A two-layer defense against leaked credentials: a Gitleaks pre-commit hook that blocks any local commit containing API keys or tokens, plus a matching GitHub Actions check that catches anything that slips past (or around) the hook.

Prerequisites

  • Gitleaks v8.30.1 (current stable; anything ≥ v8.19 works, since that's where the modern git subcommand landed)
  • pre-commit 4.6.x — the pre-commit framework manages the hook so teammates get it with one command
  • Git and a GitHub repository you can push to
  • macOS or Linux with Homebrew, or grab binaries from the Gitleaks releases page and install pre-commit with pip install pre-commit

You don't strictly need Gitleaks installed locally — the pre-commit framework builds it for you — but having the CLI around is useful for one-off scans.

Step 1: Install the tools

brew install gitleaks pre-commit

Confirm both are on your PATH:

gitleaks version   # 8.30.1
pre-commit --version   # pre-commit 4.6.1

Step 2: Add the pre-commit hook

In your repo root, create .pre-commit-config.yaml:

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.30.1
    hooks:
      - id: gitleaks

Then install the hook into .git/hooks:

pre-commit install

Under the hood this hook runs gitleaks git --pre-commit --redact --staged --verbose — it scans only your staged changes (fast) and redacts the secret in its output so the leak doesn't also end up in your terminal scrollback or CI logs.

The first commit after installing is slow: pre-commit downloads a Go toolchain and compiles Gitleaks into a cached environment. Every run after that is near-instant. If you'd rather use your Homebrew-installed binary, swap id: gitleaks for id: gitleaks-system.

Commit the config so the hook ships with the repo — teammates just run pre-commit install once after cloning:

git add .pre-commit-config.yaml
git commit -m "Add gitleaks pre-commit hook"

Step 3: Add the CI check

Local hooks are advisory — anyone can skip them with git commit --no-verify. The CI check is the enforcement layer. Create .github/workflows/gitleaks.yml:

name: gitleaks
on:
  pull_request:
  push:
  workflow_dispatch:
jobs:
  scan:
    name: gitleaks
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v3
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}

fetch-depth: 0 matters — gitleaks-action scans commit history, not just the checkout, so it needs more than a shallow clone. GITHUB_TOKEN is provided automatically and lets the action comment on PRs that contain leaks. GITLEAKS_LICENSE is only required for organization-owned repos (see Troubleshooting); on a personal repo the line is harmless.

Push, then make this check required under Settings → Branches → Branch protection rules so a red scan actually blocks merges.

Verify it works

Stage a fake AWS access key and try to commit it:

echo 'AWS_ACCESS_KEY_ID=AKIAQ4KMGN37VPXHW2TR' > .env
git add .env
git commit -m "add config"

The commit should be rejected with output like:

Detect hardcoded secrets using Gitleaks..................................Failed
- hook id: gitleaks
- exit code: 1

Finding:     AWS_ACCESS_KEY_ID=REDACTED
Secret:      REDACTED
RuleID:      aws-access-token
Entropy:     4.121928
File:        .env
Line:        1
Fingerprint: .env:aws-access-token:1

1:04PM INF scanning staged changes
1:04PM WRN leaks found: 1

Exit code 1 means leaks were found; 0 means clean. Clean up with git rm --cached .env && rm .env, then push a branch containing the same fake key to confirm the Actions run goes red too.

Troubleshooting

My test secret isn't detected. If you tested with AWS's documentation key AKIAIOSFODNN7EXAMPLE, that's expected: the aws-access-token rule has a built-in allowlist regex .+EXAMPLE$, so anything ending in EXAMPLE is deliberately ignored. Use a key like the one above.

🛑 missing gitleaks license in the Actions log. Organization-owned repos need a license for gitleaks-action (free and paid tiers exist — request one at gitleaks.io), stored as an encrypted repo secret named GITLEAKS_LICENSE. Personal accounts don't need one.

A real config value keeps getting flagged. For a known-fake secret, append a # gitleaks:allow comment to that line. Otherwise copy the Fingerprint: value from the finding into a .gitleaksignore file in the repo root — that suppresses exactly that occurrence, not the whole rule.

The hook passed but CI failed. The pre-commit hook only scans staged changes, so secrets committed before you installed it are invisible to it — CI scans full history and finds them. Audit locally with gitleaks git -v, and treat anything it finds as compromised: rotate the credential first, then clean up the history.

Next steps

  • Add a custom .gitleaks.toml with rules for your internal token formats, using [extend] useDefault = true to keep the ~180 built-in rules.
  • Generate a baseline (gitleaks git --report-path baseline.json, then --baseline-path baseline.json on later runs) to adopt Gitleaks on a legacy repo without drowning in old findings.
  • Scan non-git surfaces: gitleaks dir for arbitrary directories, gitleaks stdin for piped input — handy for checking .env files and CI artifacts that never touch git.

Sources & further reading

  1. Gitleaks README — github.com
  2. Gitleaks pre-commit hook definitions — github.com
  3. Gitleaks-Action README — github.com
  4. pre-commit framework documentation — pre-commit.com
  5. Gitleaks default ruleset (gitleaks.toml) — github.com
Emeka Okafor
Written by
Emeka Okafor · Security Editor

Emeka has spent over a decade tracking threat actors, vulnerability disclosures, and the evolving landscape of application security, bringing a sharp continent-spanning perspective to his reporting. He's known for translating dense CVE advisories into clear, actionable context that developers and security teams alike actually read.

Discussion 0

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading