## TL;DR

Read each finding and decide: real secret or false positive. A real secret means rotate it at the provider right now and purge it from git history - the PR cannot merge until the secret is dead. A false positive (fixture, example, hash shaped like a key) gets an allowlist entry in `.gitleaks.toml`. Findings that predate your branch are handled with a baseline so old leaks do not block new work.

## The error

```text
Gitleaks found 2 leaks
ERROR: leaks detected - failing the check
```

## Fix it

1. Read the findings: file, line number, and which rule fired for each leak.
   Expected: you can point at each value and say which rule flagged it and why it looks suspicious.
2. If any finding is a REAL credential, rotate it at the provider immediately, then purge it from git history (filter-repo or equivalent) and force-push the cleaned branch.
   Expected: the old credential works nowhere; the history no longer contains it.
3. If a finding is a false positive - a test fixture, a docs example, or a hash that merely looks like a key - add an allowlist entry for that path or pattern in `.gitleaks.toml`.
   Expected: re-running the scan passes with the allowlist committed.
4. If the leaks already exist on the main branch and predate your work, record a baseline so the gate only fails on newly introduced leaks, and file a separate ticket to rotate the old ones.
   Expected: your PR is unblocked; the old leaks are tracked instead of silently ignored.
5. Re-run the push or the CI check.
   Expected: gitleaks exits 0 and the branch pushes.

## Use this when

- Gitleaks fails the PR with "leaks detected" and blocks the push
- You need to tell real secrets from false positives on a review branch
- A pre-existing leak on main is blocking unrelated PRs

## Not for this skill when

- The check fails with a config error (bad TOML syntax) - fix the config file
- The scanner is a different tool (trufflehog, detect-secrets) - same workflow, different flags
- The secret is already public in git history - rotation is mandatory; allowlisting alone leaves a live credential in the open

## Variant phrasings

- gitleaks found leaks how to fix
- gitleaks false positive allowlist
- gitleaks blocked push
- gitleaks protect failed

## Why it happens

Gitleaks pattern-matches on entropy and known secret formats, and fixtures plus hashes look exactly like secrets to a regex. The gate fails closed deliberately: a real leaked credential sitting in history is a security incident, so the default is to block and let a human sort real from fake.

## Edge cases

- Rotating without purging history leaves the secret in the repo - always do both, in that order
- Allowlisting by path is safer than by regex; broad regexes over-suppress and hide future real leaks
- A baseline hides old leaks from the gate - pair it with a rotation ticket so they are actually fixed
- Scanner version bumps add new rules, so a branch that was green can go red after an upgrade - pin the gitleaks version in CI

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_KJ9zOXLxCo-fw-q3MKWD0g
