Gitleaks tutorial: scanning repos, CI, and beyond

The leak is already in your git history. Not in a branch you can delete — in the commit graph, where every clone carries it. Gitleaks is the open-source scanner teams use to find those secrets before an attacker does, and it earns its place in local workflows and CI pipelines.

Why history is the hard part

A secret pushed in a commit stays in the repository forever, or at least until someone rewrites history and every clone is force-updated. Scanning the working tree misses the problem entirely, because the secret may have been removed from the latest commit months ago. Gitleaks scans the commit history itself, which is what makes it useful for retroactive detection rather than just pre-commit hygiene.

Scanning a repository

Gitleaks ships as a single binary, which keeps setup boring. To scan the current repository:

gitleaks detect --source . --report-path report.json --report-format json

The default ruleset covers common credential shapes — API keys for major providers, private keys, tokens in URLs. Two flags matter for real use:

  • --redact masks the found secret in output, so a report shown on a shared screen does not leak the very value you are hunting.
  • --verbose shows which rule matched, which is how you learn whether a finding is real or a false positive.

For a quick check of the working tree only — fast but shallow — gitleaks protect scans staged and unstaged changes instead.

Wiring it into CI

History scanning is a batch job; CI is where gitleaks earns its keep. On push, run detection against the full history and fail the build on findings — gitleaks returns a nonzero exit code when leaks are found, exactly the signal a CI gate wants. For pull requests, scan the commit range between the base branch and the PR head so only new code is judged. GitHub Actions users can use the official action or invoke the binary directly; either way, keep reports small and redacted.

Scan on every push, not just at release time. A leak found in a PR review costs one rebase; a leak found in production costs a rotation, a notification, and a post-mortem.

Rules: fewer, tuned, owned

The default rules are a starting point, not a policy. Teams quickly learn their own false-positive patterns — example strings in tests, documentation placeholders — and extend the config with allowlists. Custom rules and per-rule allowlists let the scanner get quieter over time without getting weaker. The deeper point: the rule set is a living artifact — review it when you add a vendor or credential format, and prune rules you never match.

Beyond git

The same matching engine that scans commits can scan other things: log directories, export dumps, config backups. Gitleaks’ dir mode covers exactly this case: scanning a directory that is not a repository. Secrets do not only live in git, and neither should your scanning. The rule corpus is also MIT-licensed and has been reused beyond the tool itself, for example as the foundation of DLP pattern layers in other projects — trustless bundles 40 gitleaks-derived rules, with attribution in NOTICE, for scanning agent traffic and retroactively scrubbing logs.

What a finding means

A confirmed leak is a rotation event, not a deletion task. Removing the string from history (via filter-repo or similar) matters for hygiene, but the credential is already in the wild: rotate first, then clean up. For API keys, invalidate at the provider; for private keys, revoke and reissue. Treat the scan finding as the start of the incident response, not the end of it.

trustless is an open-source credential broker whose DLP layer reuses the gitleaks rule corpus for real-time masking and retroactive log scrubbing — a natural complement to scanning git. If you scan only git today, which of your non-git stores — logs, exports, agent transcripts — do you already know are clean?