# Repository History Purge Runbook

Date: 2026-02-15  
Scope: purge secret-bearing blobs from Git history before production cut

## Objective

Rewrite repository history to remove any accidental secret-bearing files/commits, then force-push sanitized history in a controlled window.

## Preconditions

- Freeze merges to `main`.
- Rotate all potentially exposed credentials first.
- Ensure repository admins are present for coordinated force-push and branch protection updates.

## Tooling

- Preferred: `git filter-repo` (fast, maintainable)
- Alternate: BFG Repo-Cleaner

## Procedure (git filter-repo)

1. Mirror clone:
```bash
git clone --mirror https://github.com/<org>/<repo>.git
cd <repo>.git
```

2. Remove known sensitive paths:
```bash
git filter-repo --path .env --path .env.production --path-glob "*.pem" --invert-paths
```

3. Scrub sensitive patterns from remaining blobs:
```bash
git filter-repo --replace-text ../replace-secrets.txt
```

`replace-secrets.txt` format example:
```text
regex:sk-[A-Za-z0-9_-]{20,}==>REDACTED_OPENAI_KEY
regex:AKIA[0-9A-Z]{16}==>REDACTED_AWS_KEY
```

4. Validate purge:
```bash
git log --all --name-only | grep -E "(.env|\\.pem)$" || true
```

5. Force-push rewritten history:
```bash
git push --force --all
git push --force --tags
```

## Post-Purge Actions

- Invalidate old clones:
  - team must re-clone or hard reset to rewritten history
- Re-enable branch protection rules
- Re-run security workflows (gitleaks + secret hygiene)
- Document purge commit window and impacted refs

## Safety Notes

- Do not run this on an active branch with uncoordinated contributors.
- Purge is destructive and irreversible on rewritten refs.
