> ## Documentation Index
> Fetch the complete documentation index at: https://docs.iriscode.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Git History Secrets Scan: Find Credentials Your History Still Remembers

> Iris Code walks your git commit history and finds secrets that were committed and later removed - deduplicated, always masked, and fully local. Available in the sidebar and as iris secrets --history.

The working tree can be clean while a secret still sits in an old commit. Deleting a hardcoded key from a file removes it from the *present* - git history keeps every version that was ever committed. The history secrets scan (**Pro**) walks past commits through the same two-layer [secrets detection](/enforcement/hardcoded-secrets) that scans your working tree, and tells you what history still remembers.

## How it works

Every file version **introduced** by each commit - added or modified, including committed `.env` files - runs through the secrets engine. The scan never re-analyses unchanged files, so it stays fast even on long histories.

* **One finding per distinct secret.** The same key committed in ten places reports once, with its first and last sighting, the number of commits, and every file involved.
* **Always masked.** Findings carry a masked value (`sk_live_****`) - the raw value never leaves the analysis engine and never appears in any output, panel, or JSON export.
* **HEAD status.** Each finding shows whether the secret is *still in HEAD* (click to open the exact line) or *historical-only* - removed since, but still in history.
* **Merge commits covered.** Content introduced by a merge itself (for example a conflict resolution) is scanned too.
* **Fully local.** The scan shells out to your local `git` - no code, no history, and no findings leave your machine.

## Running it

**In VS Code (Pro):** open the Workspace tab, expand **Security Posture**, and select **Scan git history for secrets** - or run *Iris Code: Scan Git History for Secrets* from the Command Palette. A progress notification tracks the walk and the results open in a dedicated panel with still-in-HEAD/historical filters and search.

**In the terminal (Pro):**

```bash theme={null}
iris secrets --history              # last 50 commits
iris secrets --history --depth 500  # last 500 commits
iris secrets --history --depth 0    # the full history
iris secrets --history --format json --output history-scan.json
```

The command exits `1` if any secret is found in the scanned range, so it can gate CI.

## Coverage is always disclosed

A security scan that silently covers less than it implies is worse than no scan. Every limit is reported with the result:

| Limit           | Default    | What you see                                                              |
| --------------- | ---------- | ------------------------------------------------------------------------- |
| Depth           | 50 commits | "history continues beyond depth 50 - rerun with `--depth 0`"              |
| Per-file size   | 1 MiB      | counted in the skipped-blobs total                                        |
| Total scan size | 50 MiB     | "depth reduced to N of M commits (size cap)" - newest commits are kept    |
| Shallow clone   | -          | "this is a shallow clone - run `git fetch --unshallow` for full coverage" |

## What to do with a finding

**Rotate the credential.** That is the fix, even for historical-only findings - anyone who ever had access to the repository may have the value. Removing the secret from history itself requires a rewrite (`git filter-repo`), and rotation is required regardless of whether you rewrite.
