git-leaks: Stop Secrets Before They Ship
Security First — Part 4 of 30
The Thirty-Second Audit That Ruined Someone's Day
Late December 2025, a developer posted a simple story to r/vibecoding: a friend had asked them to review a freshly vibe-coded mobile app. Thirty seconds later, they had found an OpenAI API key hardcoded directly in the app bundle — readable by anyone who downloaded the app. The post racked up 277 upvotes and 134 comments, most of them along the lines of "this happens constantly."
It does. And the numbers behind it are staggering.
In March 2026, GitGuardian released its 5th annual State of Secrets Sprawl report. The headline: approximately 29 million secrets were detected on public GitHub in 2025, a 34% year-over-year jump — the largest single-year increase ever recorded. Secrets tied to AI services alone surged 81%, reaching over 1.27 million leaked credentials including LLM API keys, vector database tokens, and orchestration platform secrets. Developers using AI coding tools like Claude Code showed a 3.2% secret leak rate, more than double the 1.5% baseline for all GitHub commits.
Here's the part that should keep you up at night: 70% of secrets leaked in 2022 are still valid today. That means a key you accidentally committed three years ago is probably still live, still usable, still waiting to be found by someone with bad intentions and a grep command.
The fix is not complicated. It's a tool called gitleaks, and it takes about five minutes to set up.
What gitleaks Actually Does
gitleaks is an open-source tool that scans your git repository — including its entire commit history — for secrets: API keys, passwords, tokens, connection strings, private keys. It ships with hundreds of detection rules covering AWS, OpenAI, Stripe, Twilio, GitHub, and dozens of other services.
More importantly, gitleaks can run as a pre-commit hook — meaning it scans your staged changes before they ever become a commit. If it finds a secret, the commit is blocked. No secret ever touches your git history. No git history ever gets pushed to GitHub. No GitHub push ever gets scraped by a bot in under two minutes (which is roughly how fast automated scanners find newly pushed credentials).
This is "shift left" security in its most practical form: stop the problem at the source, on your own machine, before it becomes anyone else's problem.
Installing gitleaks
macOS (Homebrew):
brew install gitleaks
Linux:
# Download the latest release binary
wget https://github.com/gitleaks/gitleaks/releases/download/v8.21.2/gitleaks_8.21.2_linux_x64.tar.gz
tar -xzf gitleaks_8.21.2_linux_x64.tar.gz
sudo mv gitleaks /usr/local/bin/
Windows (via Scoop):
scoop install gitleaks
Verify it's working:
gitleaks version
Your First Scan
Before setting up a hook, run a scan on your existing repository to see if anything is already lurking:
# Scan the full history of the current repo
gitleaks detect --source . --verbose
# Output results as a JSON report
gitleaks detect --source . --report-format json --report-path secrets-report.json
If gitleaks finds something, do not just delete the file and commit again. The secret is already in your git history — every clone of your repo has a copy. You need to:
- Rotate the secret immediately. Revoke the old key and generate a new one. Assume the old key is compromised.
- Rewrite history using
git filter-repoor BFG Repo-Cleaner to physically remove it from all commits. - Force push the cleaned history.
Step 1 is non-negotiable and must happen first. Everything else is cleanup.
Setting Up the Pre-Commit Hook
This is where gitleaks earns its keep. The pre-commit framework makes this almost trivially easy:
# Install the pre-commit framework
pip install pre-commit
Create a .pre-commit-config.yaml file in your project root:
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleaks
Install the hook:
pre-commit install
That's it. Now every time you run git commit, gitleaks scans your staged changes first. If it finds a secret, your commit is blocked with a clear message telling you exactly what was found and on which line.
Test it yourself:
# Create a file with a fake secret to see it in action
echo 'OPENAI_API_KEY=sk-proj-abc123fakekey9876543210' > test-secret.txt
git add test-secret.txt
git commit -m "test"
# gitleaks should block this commit
Configuring gitleaks for Your Project
Out of the box, gitleaks works well. But you'll likely want a .gitleaks.toml config file to reduce false positives and add any custom rules for your specific stack:
# .gitleaks.toml
[extend]
useDefault = true
# Ignore example files and test fixtures
[allowlist]
description = "Safe files to ignore"
paths = [
'''vendor/''',
'''node_modules/''',
'''\.env\.example''',
'''test/fixtures/''',
]
# Ignore known placeholder values in documentation
[[rules.allowlist]]
regexes = [
'''AKIAIOSFODNN7EXAMPLE''',
'''sk-proj-EXAMPLE''',
]
The useDefault = true line pulls in gitleaks' full built-in ruleset so you get all the standard detections for AWS, GitHub, Stripe, OpenAI, and more, then you extend on top.
One More Layer: GitHub Actions
Pre-commit hooks are local, which means someone can bypass them with git commit --no-verify. For team projects or anything going to a real deployment, add gitleaks as a CI check too:
# .github/workflows/secret-scan.yml
name: Secret Scanning
on: [push, pull_request]
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 }}
The fetch-depth: 0 is critical — without it, the action only sees the latest commit, not full history.
Why This Matters Especially for Vibe Coders
If you're building with AI coding tools, you're moving fast. That speed is the point. But speed without guardrails is how 65% of the Forbes AI 50 companies ended up with verified leaked secrets on GitHub, according to a November 2025 audit by cloud security firm Wiz. These are well-funded companies with dedicated security teams.
AI assistants are genuinely good at many things, but they are trained to write functional code — not necessarily secure code. They will happily put your API key directly in a config file if you don't tell them not to. They will suggest hardcoding a database password to "get it working quickly." The --no-verify escape hatch exists, but gitleaks makes the secure path the easy path, which is the only kind of security that actually gets used.
Orca Security's 2025 State of Cloud Security Report found that 85% of organizations have plaintext secrets embedded in their source code repositories. The pre-commit hook is five minutes of setup against years of exposure.
Action Checklist
- Install gitleaks on your machine (
brew install gitleaksor equivalent) - Scan your existing repos with
gitleaks detect --source . --verbose— find out what's already there - Rotate any secrets found immediately, before doing anything else
- Install pre-commit (
pip install pre-commit) and add a.pre-commit-config.yamlto your projects - Add a
.gitleaks.tomlto reduce false positives and document intentional allowlists - Add gitleaks to GitHub Actions for any project with collaborators or CI/CD
- Never use
git commit --no-verifyexcept in emergencies — and treat it like a fire alarm, not a convenience - Establish a habit: before shipping any AI-generated code, ask yourself: "Did the AI put a credential anywhere in here?"
Ask The Guild
Community prompt: Have you ever found a leaked secret in your own code (or someone else's)? What happened, and what did you do about it? Share your story — the more specific the better. War stories help everyone build better habits.
Sources: GitGuardian State of Secrets Sprawl 2026 via Last Watchdog | Security Ledger: AI Drives 34% Surge in Exposed Secrets | The Register: AI Companies Leaking Keys on GitHub | GitGuardian State of Secrets Sprawl 2025 | OneUptime: Secret Scanning with gitleaks | Orca Security: Prevent Secrets with Git Hooks