Metadata-Version: 2.4
Name: secret-time-machine
Version: 1.0.0
Summary: Scan git history for secrets, API keys, and passwords — even ones deleted long ago.
Author: secret-time-machine contributors
License: MIT
Project-URL: Homepage, https://github.com/yourusername/secret-time-machine
Project-URL: Repository, https://github.com/yourusername/secret-time-machine
Project-URL: Issues, https://github.com/yourusername/secret-time-machine/issues
Keywords: security,git,secrets,api-keys,credentials,history,audit,devops,devsecops
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Version Control :: Git
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: rich>=13.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: isort>=5.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: flake8>=6.0; extra == "dev"
Dynamic: license-file

# secret-time-machine

> "The Past is Not Private"

A Python CLI tool that scans the **entire git history** of a repository for secrets, API keys, passwords, and tokens — including ones that were "deleted" long ago. `git rm` does not erase history. Every secret ever committed is still there.

## Why this exists

Developers often commit secrets accidentally and then delete them with `git rm` or a follow-up commit. The secret looks gone from the working tree, but it is permanently embedded in git history. Anyone who clones the repo — now or in the future — can read every commit, including the deleted one.

`secret-time-machine` time-travels through every commit and every diff to surface those forgotten credentials.

## Installation

```bash
pip install secret-time-machine
```

Or from source:

```bash
git clone https://github.com/yourusername/secret-time-machine
cd secret-time-machine
pip install -e .
```

## Quick start

```bash
# Scan the current directory's git history
secret-time-machine

# Scan a specific repo
secret-time-machine --repo /path/to/repo

# Output JSON for CI pipelines
secret-time-machine --json

# Show full secret values (default is to redact)
secret-time-machine --show-secrets

# Get remediation instructions
secret-time-machine --remediation
```

## All options

```
Usage: secret-time-machine [OPTIONS]

Options:
  --repo PATH          Path to the git repository to scan.
  --branch TEXT        Scan only commits on this branch (default: all).
  --last N             Scan only the last N commits.
  --additions-only     Only report secrets in addition lines (+ lines).
  --json               Output results as JSON.
  --show-secrets       Show full secret values (default: redact).
  --redact             Explicitly redact secret values (this is the default).
  --remediation        Show instructions for cleaning secrets from history.
  --version            Show the version and exit.
  --help               Show this message and exit.
```

## What it detects

| Pattern | Severity |
|---------|----------|
| AWS Access Key (`AKIA...`) | HIGH |
| AWS Secret Key | HIGH |
| GitHub Token (`ghp_...`) | HIGH |
| GitHub OAuth (`gho_...`) | HIGH |
| OpenAI API Key (`sk-...`) | HIGH |
| Anthropic API Key (`sk-ant-...`) | HIGH |
| Stripe Secret Key (`sk_live_...`) | HIGH |
| Google API Key (`AIza...`) | HIGH |
| Slack Token (`xox...`) | HIGH |
| Private Keys (RSA, EC, OPENSSH) | HIGH |
| SendGrid API Key | HIGH |
| HuggingFace Token (`hf_...`) | HIGH |
| NPM Token (`npm_...`) | HIGH |
| Database URLs (postgres, mongo, redis) | HIGH |
| Generic Password (`password = "..."`) | MEDIUM |
| Generic Secret (`api_key = "..."`) | MEDIUM |
| JWT Tokens | MEDIUM |
| Heroku API Keys | MEDIUM |
| And more... | |

## Example output

```
╔══════════════════════════════════════════╗
║         SECRET TIME MACHINE              ║
║      "The Past is Not Private"           ║
╚══════════════════════════════════════════╝

Scanning: /Users/user/myproject
Commits scanned: 1,247 (across all branches)
Time range: 2021-03-14 to 2024-11-22

SECRETS FOUND IN HISTORY: 2

  x OpenAI API Key  HIGH
    Commit:  a4f8c2d  (2023-08-14 by jane@example.com)
    File:    config/settings.py
    Status:  DELETED in commit b9e3f1a — still in history, key may be compromised
    Value:   sk-••••••••••••••••••••••••XKBP

  x AWS Access Key  HIGH
    Commit:  3c7d9a1  (2022-11-30 by bob@example.com)
    File:    deploy/terraform.tf
    Status:  Still present in current codebase!
    Value:   AKIA••••••••••••MNPQ
```

## How it works

1. Runs `git log --all --format="%H %ae %aI"` to collect every commit hash across all branches.
2. For each commit, runs `git diff-tree --no-commit-id -p -r {hash}` to get the full patch.
3. Scans every line starting with `+` (additions) against all secret patterns.
4. Checks whether each found secret is still present in `HEAD` or was later deleted.
5. Reports findings sorted by severity, with optional JSON output for CI integration.

## Remediation

Run `secret-time-machine --remediation` for the full guide. Short version:

1. Use `git filter-repo` to purge secrets from history (or BFG Repo Cleaner for large repos).
2. Force-push the rewritten history.
3. Rotate every exposed credential immediately.
4. Add `.env` files to `.gitignore` and install pre-commit hooks to prevent future leaks.

## CI integration

Use the `--json` flag and check the exit code. The tool exits with code `1` if any secrets are found, `0` if the history is clean.

```yaml
# GitHub Actions example
- name: Scan git history for secrets
  run: secret-time-machine --json --additions-only > scan-results.json
  continue-on-error: true

- name: Fail if secrets found
  run: |
    count=$(jq '.summary.total_findings' scan-results.json)
    if [ "$count" -gt 0 ]; then exit 1; fi
```

## Development

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest -v

# Type checking
mypy src/

# Formatting
black .
isort .
```

## Security note

This tool calls `git` via `subprocess` with a list of arguments (never `shell=True`) and uses `shlex.quote()` for any user-provided paths, preventing shell injection attacks.

## License

MIT
