Skip to main content

A CLI tool to detect leaked secrets in Git repositories

Project description

secretleak

A production-quality CLI tool to detect leaked secrets (API keys, tokens, private keys) in Git repositories.

Features

  • Regex rules — 30+ built-in patterns covering AWS, GitHub, Stripe, Google, Slack, Twilio, SendGrid, npm, PyPI, private keys, connection strings, and more
  • Shannon entropy heuristic — catches high-entropy strings that don't match a known pattern
  • Three scan modes — working tree, staged diff (git diff --staged), commit range
  • Three output formats — Rich console table, JSON report, SARIF 2.1.0 (GitHub Code Scanning compatible)
  • False-positive suppression — allowlist patterns, ignore paths, baseline file
  • Git hook — auto-generates a pre-commit hook that blocks commits on findings
  • Secret masking — secrets are never printed or stored in full (prefix/suffix only)

Installation

From PyPI

pip install secretleak

From source (development)

git clone https://github.com/your-org/secretleak.git
cd secretleak
pip install -e ".[dev]"

Using secretleak in Another Project

Option 1 — Install globally and scan manually

Install once, then point it at any repo:

pip install secretleak
secretleak scan /path/to/your-project

Option 2 — Add as a dev dependency

In your project's pyproject.toml:

[project.optional-dependencies]
dev = [
    "secretleak",
]

Then install and scan:

pip install -e ".[dev]"
secretleak scan .

Or reference a local checkout before it is published to PyPI:

dev = [
    "secretleak @ file:///path/to/secretleak",
]

Option 3 — Pre-commit hook (recommended for teams)

Run once inside the target repo. Every developer on the team is protected automatically — no changes to their workflow required.

cd /path/to/your-project
secretleak install-hook .

From that point on, every git commit scans the staged files and blocks if secrets are found:

[secretleak] Scanning staged files for secrets...
🔴 CRITICAL  AWS Access Key ID — config.py:12 — AKIA****MPLE

[secretleak] !! Commit BLOCKED: secrets detected in staged files.

Remove the hook at any time:

secretleak uninstall-hook .

Option 4 — GitHub Actions (CI/CD)

Create .github/workflows/secret-scan.yml in your project:

name: Secret Scan

on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
      - uses: actions/checkout@v4

      - name: Scan for secrets
        run: |
          pip install secretleak
          secretleak scan . --format sarif --output results.sarif --no-fail

      - name: Upload to GitHub Code Scanning
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Findings appear in your repo's Security → Code Scanning tab with file locations and line numbers.

Option 5 — Suppress false positives in your project

cd /path/to/your-project

# 1. Generate a baseline to silence already-known findings
secretleak generate-baseline .
git add .secretleak-baseline.json
git commit -m "chore: add secretleak baseline"

# 2. Add project-specific config
cat > .secretleak.yaml << 'EOF'
allowlist:
  patterns:
    - '^EXAMPLE_'        # placeholder values in docs
    - 'your-key-here'    # obvious dummy values
  paths:
    - tests/fixtures/**  # test data with fake secrets
    - docs/**
baseline_file: .secretleak-baseline.json
EOF

Future scans will skip anything in the baseline and anything matching the allowlist.


Quick reference

Goal Command
Scan a project secretleak scan /path/to/project
Scan staged files only secretleak scan --staged
Scan a commit range secretleak scan --commit-range HEAD~10..HEAD
Block commits automatically secretleak install-hook . (run once)
CI pipeline (SARIF) secretleak scan . --format sarif --no-fail
JSON report secretleak scan . --format json -o report.json
Suppress known findings secretleak generate-baseline .
List active rules secretleak rules

Quick Start

# Scan current directory
secretleak scan .

# Scan only staged files (before committing)
secretleak scan --staged

# Scan a commit range
secretleak scan --commit-range HEAD~10..HEAD

# JSON output
secretleak scan . --format json --output report.json

# SARIF output (GitHub Code Scanning)
secretleak scan . --format sarif --output results.sarif

# Install pre-commit hook
secretleak install-hook .

# Generate baseline to suppress existing findings
secretleak generate-baseline .

# List active rules
secretleak rules

Configuration

Create .secretleak.yaml in your repo root:

# Override entropy settings
entropy:
  enabled: true
  threshold: 4.5
  min_length: 20

# Add custom rules
rules:
  - id: my-internal-token
    name: Internal Service Token
    pattern: 'myapp_[a-z0-9]{32}'
    severity: high
    description: Internal service authentication token

# Allowlist – suppress known false positives
allowlist:
  patterns:
    - '^EXAMPLE'          # example values in docs
    - 'placeholder'        # obvious placeholders
  paths:
    - tests/fixtures/**   # test data
    - '**/*.md'           # documentation

# Additional paths to skip
ignore_paths:
  - vendor/**
  - node_modules/**

# Point at a baseline file
baseline_file: .secretleak-baseline.json

False Positive Handling

Allowlist patterns

allowlist:
  patterns:
    - '^fake_'
    - 'example\.com'

Baseline suppression

Generate a baseline from the current state of your repo, commit it, and future scans will ignore already-known findings:

secretleak generate-baseline .
git add .secretleak-baseline.json
git commit -m "chore: add secretleak baseline"

Ignore paths

ignore_paths:
  - docs/**
  - tests/fixtures/**
  - '**/*.lock'

CI Integration

# .github/workflows/secret-scan.yml
- name: Scan for secrets
  run: |
    pip install secretleak
    secretleak scan . --format sarif --output results.sarif --no-fail

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Git Hook

# Install
secretleak install-hook .

# Force-overwrite an existing hook
secretleak install-hook . --force

# Uninstall
secretleak uninstall-hook .

The hook runs secretleak scan --staged and blocks the commit if any secrets are found.

Output Formats

Console (default)

Rich table with severity icons, file paths, line numbers, and masked secrets.

JSON

{
  "version": "0.1.0",
  "generated_at": "2026-03-09T12:00:00Z",
  "scan_mode": "working_tree",
  "summary": { "total": 2, "critical": 1, "high": 1 },
  "findings": [
    {
      "fingerprint": "a3b4c5d6e7f8a1b2",
      "rule_id": "aws-access-key-id",
      "severity": "critical",
      "file_path": "config.py",
      "line_number": 12,
      "secret_masked": "AKIA****MPLE",
      ...
    }
  ]
}

SARIF 2.1.0

Compatible with GitHub Code Scanning. Upload via github/codeql-action/upload-sarif.

Exit Codes

Code Meaning
0 No findings
1 Findings detected (--no-fail to suppress)
2 Error (bad args, git failure, config error)

Development

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

# Run tests
pytest

# Run tests with coverage
pytest --cov=secretleak --cov-report=term-missing

# Lint
ruff check src/ tests/
ruff format src/ tests/

# Type check
mypy src/

Security Notes

  • Secrets are never stored or logged in full. Only a masked form (prefix****suffix) appears in output.
  • The JSON and SARIF outputs are safe to store and share — they contain only masked values.
  • The baseline file contains only fingerprints (SHA-256 hashes), not secret values.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

secretleak-0.1.0.tar.gz (26.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

secretleak-0.1.0-py3-none-any.whl (24.9 kB view details)

Uploaded Python 3

File details

Details for the file secretleak-0.1.0.tar.gz.

File metadata

  • Download URL: secretleak-0.1.0.tar.gz
  • Upload date:
  • Size: 26.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for secretleak-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d9d10f0ecc50b5aedb9ae9c273f9f57aae7edc408fe20896668653a71fa55a72
MD5 27bdba96ebc0580aea6b049df21da109
BLAKE2b-256 21f05cb3d6aad587bff02830e7812ba9ebc9f4530417b654d997ee508f76aab8

See more details on using hashes here.

Provenance

The following attestation bundles were made for secretleak-0.1.0.tar.gz:

Publisher: publish.yml on Mo-Shakib/secretleak

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file secretleak-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: secretleak-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for secretleak-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 28cd29e343474eb4c2962659a74174c0906bbf3bedb4f33526fea45ec7832d41
MD5 661b03692c03133b17fc37cdd7883a92
BLAKE2b-256 f1d112b46b93edc8805386d6f3dc5a52f52e91a0aab285671a957e687c8fb23a

See more details on using hashes here.

Provenance

The following attestation bundles were made for secretleak-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Mo-Shakib/secretleak

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page